100% found this document useful (1 vote)
2 views

Mastering PHP design patterns develop robust and reusable code using a multitude of design patterns for PHP 7 Ali instant download

Ebook installation

Uploaded by

schonrehald4
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
2 views

Mastering PHP design patterns develop robust and reusable code using a multitude of design patterns for PHP 7 Ali instant download

Ebook installation

Uploaded by

schonrehald4
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 60

Mastering PHP design patterns develop robust and

reusable code using a multitude of design


patterns for PHP 7 Ali download

https://textbookfull.com/product/mastering-php-design-patterns-
develop-robust-and-reusable-code-using-a-multitude-of-design-
patterns-for-php-7-ali/

Download more ebook from https://textbookfull.com


We believe these products will be a great fit for you. Click
the link to download now, or visit textbookfull.com
to discover even more!

PHP 8 Objects, Patterns, and Practice: Mastering OO


Enhancements, Design Patterns, and Essential
Development Tools Zandstra

https://textbookfull.com/product/php-8-objects-patterns-and-
practice-mastering-oo-enhancements-design-patterns-and-essential-
development-tools-zandstra/

Design Patterns in PHP and Laravel 1st Edition Kelt


Dockins

https://textbookfull.com/product/design-patterns-in-php-and-
laravel-1st-edition-kelt-dockins/

MASTERING JAVASCRIPT DESIGN PATTERNS create scalable


and reliable applications with advanced Javascript
design patterns using reliable code 3rd Edition Tomas
Corral Cosas
https://textbookfull.com/product/mastering-javascript-design-
patterns-create-scalable-and-reliable-applications-with-advanced-
javascript-design-patterns-using-reliable-code-3rd-edition-tomas-
corral-cosas/

Design Patterns in Modern C++: Reusable Approaches for


Object-Oriented Software Design 1st Edition Dmitri
Nesteruk

https://textbookfull.com/product/design-patterns-in-modern-c-
reusable-approaches-for-object-oriented-software-design-1st-
edition-dmitri-nesteruk/
Puppet Best Practices Design Patterns for Maintainable
Code 1st Edition Chris Barbour

https://textbookfull.com/product/puppet-best-practices-design-
patterns-for-maintainable-code-1st-edition-chris-barbour/

Design Patterns in .NET Core 3: Reusable Approaches in


C# and F# for Object-Oriented Software Design 2nd
Edition Dmitri Nesteruk

https://textbookfull.com/product/design-patterns-in-net-
core-3-reusable-approaches-in-c-and-f-for-object-oriented-
software-design-2nd-edition-dmitri-nesteruk/

Java Design Patterns A tour of 23 gang of four design


patterns in Java 1st Edition Vaskaran Sarcar

https://textbookfull.com/product/java-design-patterns-a-tour-
of-23-gang-of-four-design-patterns-in-java-1st-edition-vaskaran-
sarcar/

Java design patterns a tour of 23 gang of four design


patterns in Java 1st Edition Vaskaran Sarcar

https://textbookfull.com/product/java-design-patterns-a-tour-
of-23-gang-of-four-design-patterns-in-java-1st-edition-vaskaran-
sarcar-2/

Design Patterns by Tutorials Learning design patterns


in Swift 4 2 Joshua Greene

https://textbookfull.com/product/design-patterns-by-tutorials-
learning-design-patterns-in-swift-4-2-joshua-greene/
Mastering PHP Design Patterns

Develop robust and reusable code using a multitude of


design patterns for PHP 7

Junade Ali

BIRMINGHAM - MUMBAI
Mastering PHP Design Patterns
Copyright © 2016 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or
transmitted in any form or by any means, without the prior written permission of the
publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the
information presented. However, the information contained in this book is sold without
warranty, either express or implied. Neither the author, nor Packt Publishing, and its
dealers and distributors will be held liable for any damages caused or alleged to be caused
directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the
companies and products mentioned in this book by the appropriate use of capitals.
However, Packt Publishing cannot guarantee the accuracy of this information.

First published: September 2016

Production reference: 1230916

Published by Packt Publishing Ltd.

Livery Place

35 Livery Street

Birmingham B3 2PB, UK.

ISBN 978-1-78588-713-0
www.packtpub.com
Credits

Author Copy Editor

Junade Ali Safis Editing

Reviewer Project Coordinator

Sworup Shakya Suzanne Coutinho

Commissioning Editor Proofreader

Kunal Parikh Safis Editing

Acquisition Editor Indexer

Chaitanya Nair Tejal Daruwale Soni

Content Development Editor Production Coordinator

Nikhil Borkar Aparna Bhagat

Technical Editor Cover Work

Hussain Kanchwala Aparna Bhagat


About the Author
Junade Ali was a technical lead at some of the UK's leading digital agencies and has also
worked using PHP in mission-critical road-safety systems. He loves pushing PHP to its
innovative limits. Having started his career as a web development apprentice, he still
remains engaged in the academic computer science community.

Junade, an avid contributor to the PHP community, has also spoken at PHPTek and the
Lead Developer Conference. In addition to this, Junade was interviewed by Cal Evans for
Voices of the ElePHPant, and he has appeared on the PHP Roundtable. In this spirit, Junade
is proud of his local PHP user group: PHPWarks. Currently, Junade works at CloudFlare as
a polymath, and helps make the Internet more secure and faster.

Outside of development, Junade has an interest in law and political campaigns and is a
published author on constitutional law.
About the Reviewer
Sworup Shakya has worked as a web developer for more than ten years. He started his
career as a Flash ActionScript developer, before moving on to ASP.NET MVC, and finally to
PHP. During his time as a developer, Sworup worked extensively with frameworks, be it
ASP.NET MVC or AngularJS or Laravel. However, while he was working as an
ActionScript developer, he had to create one, which gave him knowledge of design patterns
and OOP concepts that has helped him improve in order to be able to work on the
frameworks he had to work on later.

Sworup received his Bachelor of Information Technology degree from Purbanchal


University in Nepal. He currently works with Zimris Technologies Nepal Pvt. Ltd., a
subsidiary of Zimris, LLC, as a senior developer.

Sworup likes to keep on top of the current technologies, keeping an eye on StackOverflow,
Laracasts forums, and occasional podcasts. He posts on these mediums whenever he can
and is looking to start a technical blog documenting his experiences at http://sworup.com.
np/. You can reach him at [email protected].

I would like to thank Suzanne Coutinho, Francina Pinto and Chaitanya Nair of Packt Publishing for
giving me this opportunity and helping me through the review process. I would like to thank my
friends, family and colleagues for their unconditional support.
www.PacktPub.com
For support files and downloads related to your book, please visit www.PacktPub.com.

Did you know that Packt offers eBook versions of every book published, with PDF and
ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a
print book customer, you are entitled to a discount on the eBook copy. Get in touch with us
at [email protected] for more details.

At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a
range of free newsletters and receive exclusive discounts and offers on Packt books and
eBooks.

https://www.packtpub.com/mapt

Get the most in-demand software skills with Mapt. Mapt gives you full access to all Packt
books and video courses, as well as industry-leading tools to help you plan your personal
development and advance your career.

Why subscribe?
Fully searchable across every book published by Packt
Copy and paste, print, and bookmark content
On demand and accessible via a web browser
Table of Contents
Chapter 1: Why "Good PHP Developer" Isnt an Oxymoron 8
Coding style – the PSR standards 11
Revising object-oriented programming 11
Polymorphism 11
Traits (multiple inheritance) 16
Scalar type hints 19
Limiting debug access to private/protected properties 21
Setting up the environment with Composer 23
The Gang of Four (GoF) 26
Creational design patterns 27
Dependency injection 27
Structural design patterns 28
Behavioral design patterns 28
Architectural patterns 28
Summary 29
Chapter 2: Anti-Patterns 30
Why anti-patterns matter 31
Not invented here syndrome 34
Third-party dependencies with Composer 36
God objects 40
Environment variables in PHP source 43
Singletons (and why you should be using dependency injection) 44
Dependency injection 45
Database as IPC 45
Auto-increment database IDs 46
Cronjob imitating service 47
Software in place of architecture 47
Interface Bloat 49
Cart before the horse 51
Separation of development and operations 52
Excessive separation of development responsibilities 52
Error suppression operator 53
Blind faith 54
Sequential coupling 55
The big rewrite 58
Automated tests 59
Service splitting 60
Perfectly staged migrations 61
Tester-Driven Development 62
Bloated optimization 62
Analysis paralysis 63
Bikeshedding 63
Premature optimization 63
Uneducated manager syndrome 64
Wrong rocky foundations 64
Long methods 65
Magic numbers 70
Summary 70
Chapter 3: Creational Design Patterns 72
Software design process 72
Simple Factory 74
Factory Method 78
Abstract Factory pattern 82
Lazy initialization 90
Builder pattern 93
Prototype pattern 97
Summary 102
Chapter 4: Structural Design Patterns 103
Agile software architecture 104
Decorator 105
Adapter 108
Class Adapter 108
Object Adapter 110
FlyWeight 113
Composite 117
Bridge 120
Proxy pattern 123
Facade 127
Summary 130
Chapter 5: Behavioral Design Patterns 132
Personality traits for passionate programmers 133
Observer pattern (SplObserver/SplSubject) 135

[ ii ]
Iterators 139
IteratorAggregate 139
Iterator 141
The many iterators of PHP 142
Generators 143
Template Method design pattern 148
Chain of Responsibility 152
Strategy design pattern 159
Specification design pattern 163
Scheduled Task pattern 167
Summary 168
Chapter 6: Architectural Patterns 170
Model-View-Controller (MVC) 170
Service-oriented architecture 172
Microservices 173
Asynchronous queueing 177
Message Queue pattern (Getting started with RabbitMQ) 177
Publish-Subscriber pattern 187
Summary 191
Chapter 7: Refactoring 192
What is refactoring? 192
Test, test, and test again 193
Code smells 194
Long methods and duplicated code 195
Large class 197
Replacing complex logical statements and switch statements with
polymorphism or the Strategy Pattern 198
Duplicating code following a single control structure 200
Long Parameter List and primitive obsession 200
Indecent exposure 203
Feature envy 204
Inappropriate intimacy 206
Deeply nested statements 206
Remove assignments to parameters 207
Comments 208
Encapsulating Composite with Builder 208
Replacing hard-coded notifications with Observer 209
Replacing one/many distinctions with Composite 209

[ iii ]
Separate versions with Adapters 210
What do I tell my manager? 210
Summary 211
Chapter 8: How to Write Better Code 212
Nature of a HTTP request 212
RESTful API design 231
Stateless nature 231
Versioning 231
Filtering 232
Sorting 232
Searching 232
Limiting fields 233
Returning new fields 233
When in doubt – KISS 233
Software development life cycle 234
On Scrum, and real Agility 235
You need to sack people sometimes 237
Lean project management 239
YAGNI and defering decisions 239
Monitoring 240
Tests fight legacy 241
Behavior-Driven Development 243
Summary 250
Index 252

[ iv ]
Preface
Have you ever been to a PHP conference? If not, I’d highly recommend it, it is the closest
you can get to a living and breathing PHP community. A few weeks ago, I flew from
London to St. Louis, Misouri, to speak at php[tek] (the PHP conference run by
php[architect]). After the conference, there was a small tradition within the PHP community
known as WurstCon. Essentially, hundreds of PHP conference attendees cram themselves
into a small hot dog shop and host a hot dog convention, often to the complete surprise of
the staff there. Likewise, community nights at PHP events are the warmest and most
accepting community occasions you’ll ever run into; the PHP community is surely one that
other development language communities envy.

As of PHP 7, the PHP project has changed dramatically; but what I love, remains strong.
The warmth you will feel at any PHP conference, the openness in the documentation, and
adoption in the language. Yes, there are practices that are undoubtedly bad within PHP
itself; however, think of what the PHP community has recently achieved, ranging from
PHPUnit to Composer. Throughout this book, bear in mind the improvements in PHP 7, a
few of which I’ll share with you. The trajectory of the project is now certainly upwards, and
let’s not forget that this wasn’t always true. The PHP community has learned its lessons
from the past, whilst the language maintains the flexibility to write what is bad.

This book will seek to impart strong software engineering skills to you with the focus on
implementing them in PHP. At the time of publishing this book, there is a certain void and
a necessity for this kind of material. This book seeks to be the lighthouse that will not only
demonstrate software design theory, but also seek to impart practical information of real
value to improve the quality and maintainability of the code you write. This book leaves no
stone unturned throughout the software development cycle and will seek to confront the
reasons as to why the majority of software projects fail whilst also addressing design,
redesign, and safeguard effective code.

This book goes beyond traditional design patterns as envisaged by the Gang of Four and
details the practices that passionate PHP developers need to be successful as software
engineers or leads on detailed PHP projects. This book will introduce you to the core
knowledge required to understand project management techniques, why the majority
software development projects fail, and why you can make yours a success.
Preface

Originally, I gave thought to writing a book on PHP when Mandi Rose, who I worked with
previously, suggested I put together a book on the practices I’ve learned with PHP.
Needless to say, at the time that suggestion was made, the best of my career was
undoubtedly ahead of me; when the opportunity actually arose to write something like this,
I felt I had learned dramatically more as time progressed. By no means should you see this
book as the be-all and end-all of PHP practices; instead, you should use it to increase your
knowledge base on PHP, but by no means limit it to this. In this book, I aim to give
something, however small, back to the PHP community; after reading this book, I would
encourage you to get stuck in and share what you’ve learned with others.

Later in this book, I will advocate Extreme Programming as a methodology and courage as
a key value of this methodology. I will ask you to bear in mind the explanation of courage
in The Values of Extreme Programming: “We will tell the truth about progress and
estimates. We don't document excuses for failure because we plan to succeed. We don't fear
anything because no one ever works alone. We will adapt to changes whenever they
happen.” This is, of course, some key advice we should all follow and seek to genuinely
understand risks instead of cowering behind them. For many of us, the code we write
during parts of our career is the highest expression of our labor. Indeed, the late nights
turning into early mornings we spend debugging and developing are what ultimately allow
us to demonstrate the fruits of our labor. In essence, as software engineers, the code we
write defines who we are, as such we should be open to constantly refining and refactoring
our processes, which is what this book aims to support you in doing. I am incredibly
honored that you chose to allow me to help you to reach this end.

What this book covers


Chapter 1, Why "Good PHP Developer" Isn't an Oxymoron, introduces the concept of design
patterns as recurring solutions to commonly arising problems.

Chapter 2, Anti-Patterns, introduces how patterns can lead to decidedly negative


consequences.

Chapter 3, Creational Design Patterns, discusses Gang of Four design patterns, namely those
surrounding object creation.

Chapter 4, Structural Design Patterns, covers how multiple classes and objects can be
combined to deliver a clearer interface.

[2]
Preface

Chapter 5, Behavioral Design Patterns, explains how to increase the flexibility of


communication between objects by identifying patterns that can help with communication
between them.

Chapter 6, Architectural Patterns, revolves around resolving common issues related to the
architecture of a web application/system, potentially outside the code base itself.

Chapter 7, Refactoring, shows how to redesign code that has already been written to
improve maintainability.

Chapter 8, How to Write Better Code, covers a range of concepts that haven’t been discussed
elsewhere, and it also concludes with some advice for developers.

What you need for this book


An installation of PHP 7 will serve you well throughout this book. You should be prepared
to alter your development environment as needed throughout this book; we will address
the installation of various tools as we encounter them.

This book is not for the despairingly hostile or those who are passively antagonistic to
approaching new software engineering principles. It is not for those who seek to be lone
warriors, either. When altering a given code base, you must seek to improve the code of the
entire code base and everyone who works on it. You must be willing to take personal
responsibility of the code you write and not blame external factors. Code maintainability
cannot be improved unilaterally on shared code bases; you must write your code with the
intention of maintaining code quality for those who maintain it after you. Additionally, seek
to go into this book with the mindset of being able to share what you’ve learned, whether it
is with those in your teams, your user groups, or the larger PHP community. In other
words, approach this book with the end in mind; approach this book with the stated aim of
improving your code and those in the code base you maintain.

Who this book is for


This book is certainly aimed at the PHP developer looking to learn about the complete set of
skills needed to be a software engineer, in particular, some lessons from software design;
this book will seek to educate you on how your code can be made more extensible and
easier to develop on. This book seeks to take your code beyond just being a bag of functions
and classes, instead preferring well-designed, well-written, and well-tested code.

[3]
Preface

You will need a working knowledge of PHP and enough to build an application, but by no
means do you have to be a total expert at everything in PHP; a working knowledge of the
basics of software engineering will certainly give you a heads up.

You must encounter this book with an open mind and a willingness to have your
preconceptions about software development challenged. This book will confront some
truths about how you may be failing personally as a developer; it is vital that you approach
this book with a willingness to take these principles onboard.

This book presents a set of software development patterns and principles that you can
adopt. It is vital that you understand where these patterns should and shouldn’t be applied;
this will be explained throughout the book, especially in the last chapter.

A key tenet of reading this book is understanding what PHP is for and what it isn’t. I expect
you to enter this book understanding what problems you expect PHP to solve and what
you expect to use other software development languages to solve.

Conventions
In this book, you will find a number of text styles that distinguish between different kinds
of information. Here are some examples of these styles and an explanation of their meaning.

Code words in text, database table names, folder names, filenames, file extensions,
pathnames, dummy URLs, user input, and Twitter handles are shown as follows: "The
index.php file now yields this result".

A block of code is set as follows:


<?php

abstract class Notifier


{
protected $to;

public function __construct(string $to)


{
$this->to = $to;
}

abstract public function validateTo(): bool;

abstract public function sendNotification(): string;

[4]
Preface

Any command-line input or output is written as follows:


echo $richard->hasPaws;

New terms and important words are shown in bold. Words that you see on the screen, for
example, in menus or dialog boxes, appear in the text like this: "direct your web browser to
your chosen web server and you should see Hello world! pop up on screen."

Warnings or important notes appear in a box like this.

Tips and tricks appear like this.

Reader feedback
Feedback from our readers is always welcome. Let us know what you think about this
book—what you liked or disliked. Reader feedback is important for us as it helps us
develop titles that you will really get the most out of.

To send us general feedback, simply e-mail [email protected], and mention the


book's title in the subject of your message.

If there is a topic that you have expertise in and you are interested in either writing or
contributing to a book, see our author guide at www.packtpub.com/authors.

Customer support
Now that you are the proud owner of a Packt book, we have a number of things to help you
to get the most from your purchase.

Downloading the example code


You can download the example code files for this book from your account at http://www.p
acktpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.c
om/support and register to have the files e-mailed directly to you.

[5]
Preface

You can download the code files by following these steps:

1. Log in or register to our website using your e-mail address and password.
2. Hover the mouse pointer on the SUPPORT tab at the top.
3. Click on Code Downloads & Errata.
4. Enter the name of the book in the Search box.
5. Select the book for which you're looking to download the code files.
6. Choose from the drop-down menu where you purchased this book from.
7. Click on Code Download.

You can also download the code files by clicking on the Code Files button on the book's
webpage at the Packt Publishing website. This page can be accessed by entering the book's
name in the Search box. Please note that you need to be logged in to your Packt account.

Once the file is downloaded, please make sure that you unzip or extract the folder using the
latest version of:

WinRAR / 7-Zip for Windows


Zipeg / iZip / UnRarX for Mac
7-Zip / PeaZip for Linux

The code bundle for the book is also hosted on GitHub at https://github.com/PacktPubl
ishing/Mastering-PHP-Design-Patterns/. We also have other code bundles from our
rich catalog of books and videos available at https://github.com/PacktPublishing/.
Check them out!

Errata
Although we have taken every care to ensure the accuracy of our content, mistakes do
happen. If you find a mistake in one of our books—maybe a mistake in the text or the
code—we would be grateful if you could report this to us. By doing so, you can save other
readers from frustration and help us improve subsequent versions of this book. If you find
any errata, please report them by visiting http://www.packtpub.com/submit-errata,
selecting your book, clicking on the Errata Submission Form link, and entering the details
of your errata. Once your errata are verified, your submission will be accepted and the
errata will be uploaded to our website or added to any list of existing errata under the
Errata section of that title.

[6]
Preface

To view the previously submitted errata, go to https://www.packtpub.com/books/conten


t/support and enter the name of the book in the search field. The required information will
appear under the Errata section.

Piracy
Piracy of copyrighted material on the Internet is an ongoing problem across all media. At
Packt, we take the protection of our copyright and licenses very seriously. If you come
across any illegal copies of our works in any form on the Internet, please provide us with
the location address or website name immediately so that we can pursue a remedy.

Please contact us at [email protected] with a link to the suspected pirated material.

We appreciate your help in protecting our authors and our ability to bring you valuable
content.

Questions
If you have a problem with any aspect of this book, you can contact us
at [email protected], and we will do our best to address the problem.

[7]
Why "Good PHP Developer"
1
Isnt an Oxymoron
Back in 2010, MailChimp published a post on their blog, entitled Ewww, You Use PHP? In
this blog post, they described the horror when they explained their choice of PHP to
developers who consider the phrase good PHP programmer an oxymoron. In their rebuttal
they argued that their PHP wasn't your grandfathers PHP and that they use a sophisticated
framework. I tend to judge the quality of PHP on the basis of, not only how it functions, but
how secure it is and how it is architected. This book focuses on ideas of how you should
architect your code. The design of software allows for developers to ease the extension of
the code beyond its original purpose, in a bug-free and elegant fashion.

As Martin Fowler put it:

“Any fool can write code that a computer can understand. Good programmers write code
that humans can understand.”

This isn't just limited to code style, but how developers architect and structure their code.
I've encountered many developers with their noses constantly stuck in the documentation,
copying and pasting bits of code until it works; hacking snippets together until it works.
Moreover, I far too often see the software development process rapidly deteriorate as
developers ever more tightly couple their classes with functions of ever increasing length.

Software engineers mustn't just code software; they must know how to design it. Indeed
often a good software engineer, when interviewing other software engineers will ask
questions about the design of the code itself. It is trivial to get a piece of code that will
execute, and it is also benign to question a developer as to whether strtolower or
str2lower is the correct name of a function (for the record, it's strtolower). Knowing the
difference between a class and an object doesn't make you a competent developer; a better
interview question would, for example, be how one could apply subtype polymorphism to
Why "Good PHP Developer" Isnt an Oxymoron

a real software development challenge. Failure to assess software design skills dumbs down
an interview and results in there being no way to differentiate between those who are good
at it, and those who aren't. These advanced topics will be discussed throughout this book,
by learning these tactics, you will better understand what the right questions to ask are
when discussing software architecture.

Moxie Marlinspike once tweeted the following:

“As a software developer, I envy writers, musicians, and filmmakers. Unlike software,
when they create something it is really done, forever”.

When developing software, we mustn't forget we are authors, not just of instructions for a
machine, but we are also authoring something that we later expect others to extend upon.
Therefore, our code mustn't just be targeted at machines, but humans also. Code isn't just
poetry for a machine, it should be poetry for humans also.

This is, of course, better said than done. In PHP, this may be found especially difficult given
the freedom PHP offers developers on how they may architect and structure their code. By
the very nature of freedom, it may be both used and abused, so it is true with the freedom
offered in PHP.

Therefore, it is increasingly important that developers understand proper software design


practices to ensure their code maintains the long term maintainability. Indeed, another key
skill lies in refactoring code, improving the design of existing code to make it easier to extend
in the long term.

Technical debt, the eventual consequence of poor system design, is something that I've
found comes with the career of a PHP developer. This has been true for me whether it has
been dealing with systems that provide advanced functionality or simple websites. It
usually arises because a developer elects to implement a bad design for a variety of reasons;
this is when adding functionality to an existing codebase or taking poor design decisions
during the initial construction of software. Refactoring can help us address these issues.

SensioLabs (the creators of the Symfony framework) have a tool called Insight that allows
developers to calculate the technical debt in their own code. In 2011, they did an evaluation
of technical debt in various projects using this tool; rather unsurprisingly they found that
WordPress 4.1 topped the chart of all platforms they evaluated with them claiming it would
take 20.1 years to resolve the technical debt that the project contains.

[9]
Why "Good PHP Developer" Isnt an Oxymoron

Those familiar with the WordPress core may not be surprised by this, but this issue of
course is not only associated to WordPress. In my career of working with PHP, from
working with security critical cryptography systems to working with systems that work
with mission critical embedded systems, dealing with technical debt comes with the job.
Dealing with technical debt is not something to be ashamed of for a PHP developer, indeed
some may consider it courageous. Dealing with technical debt is no easy task, especially in
the face of an ever more demanding user base, client, or project manager; constantly
demanding more functionality without being familiar with the technical debt the project
has associated to it.

I recently e-mailed the PHP Internals group as to whether they should consider deprecating
the error suppression operator @. When any PHP function is prepended by an @ symbol, the
function will suppress an error returned by it. This can be brutal, especially where that
function renders a fatal error that stops the execution of the script, making debugging a
tough task. If the error is suppressed, the script may fail to execute without providing
developers a reason as to why this is. Usage of this operator may be described as an anti-
pattern in some situations, something we will cover in Chapter 4, Structural Design Patterns.

Despite the fact that no one objected to the fact that there were better ways of handling
errors (try/catch, proper validation) than abusing the error suppression operator and
that deprecation should be an eventual aim of PHP, it is the case that some functions return
needless warnings even though they already have a success/failure value. This means that
due to technical debt in the PHP core itself, this operator cannot be deprecated until a lot of
other prerequisite work is done. In the meantime, it is down to developers to decide the best
methodologies of handling errors. Until the inherent problem of unnecessary error
reporting is addressed, this operator cannot be deprecated. Therefore, it is down to
developers to be educated as to the proper methodologies that should be used to address
error handling and not to constantly resort to using an @ symbol.

Fundamentally, technical debt slows down development of a project and often leads to code
being deployed that is broken as developers try and work on a fragile project.

When starting a new project, never be afraid to discuss architecture as architecture meetings
are vital to developer collaboration; as one Scrum Master I've worked with said in the face
of criticism that “meetings are a great alternative to work”, he said “meetings are
work…how much work would you be doing without meetings?”.

In the rest of this chapter, we will cover the following points:

Coding style – the PSR standards


Revising object-oriented programming
Setting up the environment with Composer

[ 10 ]
Why "Good PHP Developer" Isnt an Oxymoron

Who are the Gang of Four?

Coding style – the PSR standards


When it comes to coding style, I would like to introduce you to the PSR standards created
by the PHP Framework Interop Group. Namely, the two standards that apply to coding
standards are PSR-1 (Basic Coding Style) and PSR-2 (Coding Style Guide). In addition to
this, there are PSR standards that cover additional areas, for example, as of today; the PSR-4
standard is the most up-to-date autoloading standard published by the group. You can find
out more about the standards at http://www.php-fig.org/.

Coding style being used to enforce consistency throughout a code base is something I
strongly believe in. It does make a difference to your code readability throughout a project.
It is especially important when you are starting a project (chances are you may be reading
this book to find out how to do that right) as your coding style determines the style the
developers following you in working on this project will adopt. Using a global standard
such as PSR-1 or PSR-2 means that developers can easily switch between projects without
having to reconfigure their code style in their IDE. Good code style can make formatting
errors easier to spot. Needless to say that coding styles will develop as time progresses, to
date I elect to work with the PSR standards.

I am a strong believer in the phrase: always code as if the guy who ends up maintaining your code
will be a violent psychopath who knows where you live. It isn't known who wrote this phrase
originally, but it's widely thought that it could have been John Woods or potentially Martin
Golding.

I would strongly recommend familiarizing yourself with these standards before proceeding
in this book.

Revising object-oriented programming


Object-oriented programming is more than just classes and objects; it's a whole
programming paradigm based around objects (data structures) that contain data fields and
methods. It is essential to understand this; using classes to organize a bunch of unrelated
methods together is not object orientation.

Assuming you're aware of classes (and how to instantiate them), allow me to remind you of
a few different bits and pieces.

[ 11 ]
Why "Good PHP Developer" Isnt an Oxymoron

Polymorphism
Polymorphism is a fairly long word for a fairly simple concept. Essentially, polymorphism
means the same interface is used with a different underlying code. So multiple classes could
have a draw function, each accepting the same arguments, but at an underlying level, the
code is implemented differently.

In this section, I would like to talk about Subtype Polymorphism in particular (also known
as Subtyping or Inclusion Polymorphism).

Let's say we have animals as our supertype; our subtypes may well be cats, dogs, and
sheep.

In PHP, interfaces allow you to define a set of functionality that a class that implements it
must contain, as of PHP 7 you can also use scalar type hints to define the return types we
expect.

So for example, suppose we defined the following interface:


interface Animal
{
public function eat(string $food) : bool;

public function talk(bool $shout) : string;


}

We could then implement this interface in our own class, as follows:


class Cat implements Animal {
}

If we were to run this code without defining the classes we would get an error message as
follows:
Class Cat contains 2 abstract methods and must therefore be declared
abstract or implement the remaining methods (Animal::eat, Animal::talk)

Essentially, we are required to implement the methods we defined in our interface, so now
let's go ahead and create a class that implements these methods:
class Cat implements Animal
{
public function eat(string $food): bool
{
if ($food === "tuna") {
return true;
} else {

[ 12 ]
Why "Good PHP Developer" Isnt an Oxymoron

return false;
}
}

public function talk(bool $shout): string


{
if ($shout === true) {
return "MEOW!";
} else {
return "Meow.";
}
}
}

Now that we've implemented these methods, we can then just instantiate the class we are
after and use the functions contained in it:
$felix = new Cat();
echo $felix->talk(false);

So where does polymorphism come into this? Suppose we had another class for a dog:
class Dog implements Animal
{
public function eat(string $food): bool
{
if (($food === "dog food") || ($food === "meat")) {
return true;
} else {
return false;
}
}

public function talk(bool $shout): string


{
if ($shout === true) {
return "WOOF!";
} else {
return "Woof woof.";
}
}
}

Now let's suppose we have multiple different types of animals in a pets array:
$pets = array(
'felix' => new Cat(),
'oscar' => new Dog(),

[ 13 ]
Why "Good PHP Developer" Isnt an Oxymoron

'snowflake' => new Cat()


);

We can now actually go ahead and loop through all these pets individually in order to run
the talk function. We don't care about the type of pet because the talk method that is
implemented in every class we get is by virtue of us having extended the Animals interface.

So let's suppose we wanted to have all our animals run the talk method. We could just use
the following code:
foreach ($pets as $pet) {
echo $pet->talk(false);
}

No need for unnecessary switch/case blocks in order to wrap around our classes, we just
use software design to make things easier for us in the long-term.

Abstract classes work in a similar way, except for the fact that abstract classes can contain
functionality where interfaces cannot.

It is important to note that any class that defines one or more abstract classes must also be
defined as abstract. You cannot have a normal class defining abstract methods, but you can
have normal methods in abstract classes. Let's start off by refactoring our interface to be an
abstract class:
abstract class Animal
{
abstract public function eat(string $food) : bool;

abstract public function talk(bool $shout) : string;

public function walk(int $speed): bool {


if ($speed > 0) {
return true;
} else {
return false;
}
}
}

You might have noticed that I have also added a walk method as an ordinary, non-abstract
method; this is a standard method that can be used or extended by any classes that inherit
the parent abstract class. They already have their implementation.

Note that it is impossible to instantiate an abstract class (much like it's not possible to
instantiate an interface). Instead, we must extend it.

[ 14 ]
Why "Good PHP Developer" Isnt an Oxymoron

So, in our Cat class let's remove the following:


class Cat implements Animal

We will replace it with the following code:


class Cat extends Animal

That's all we need to refactor in order to get classes to extend the Animal abstract class. We
must implement the abstract functions in the classes as we outlined for the interfaces, plus
we can use the ordinary functions without needing to implement them:
$whiskers = new Cat();
$whiskers->walk(1);

As of PHP 5.4 it has also become possible to instantiate a class and access a property of it in
one system. PHP.net advertised it as: Class member access on instantiation has been added, e.g.
(new Foo)->bar(). You can also do it with individual properties, for example, (new
Cat)->legs. In our example, we can use it as follows:

(new \IcyApril\ChapterOne\Cat())->walk(1);

Just to recap a few other points about how PHP implemented OOP, the final keyword
before a class declaration or indeed a function declaration means that you cannot override
such classes or functions after they've been defined.

So, let's try extending a class we have named as final:


final class Animal
{
public function walk()
{
return "walking...";
}
}

class Cat extends Animal


{
}

This results in the following output:


Fatal error: Class Cat may not inherit from final class (Animal)

Similarly, let's do the same except at a function level:


class Animal
{

[ 15 ]
Why "Good PHP Developer" Isnt an Oxymoron

final public function walk()


{
return "walking...";
}
}

class Cat extends Animal


{
public function walk () {
return "walking with tail wagging...";
}
}

This results in the following output:


Fatal error: Cannot override final method Animal::walk()

Traits (multiple inheritance)


Traits were introduced in PHP as a mechanism for introducing Horizontal Reuse. PHP
conventionally acts as a single inheritance language, because of the fact that you can't
inherit more than one class into a script.

Traditional multiple inheritance is a controversial process that is often looked down upon
by software engineers.

Let me give you an example of using Traits first hand; let's define an abstract Animal class
that we want to extend into another class:
class Animal
{
public function walk()
{
return "walking...";
}
}

class Cat extends Animal


{
public function walk () {
return "walking with tail wagging...";
}
}

[ 16 ]
Why "Good PHP Developer" Isnt an Oxymoron

So now let's suppose we have a function to name our class, but we don't want it to apply to
all our classes that extend the Animal class, we want it to apply to certain classes
irrespective of whether they inherit the properties of the abstract Animal class or not.

So we've defined our functions like so:


function setFirstName(string $name): bool
{
$this->firstName = $name;
return true;
}

function setLastName(string $name): bool


{
$this->lastName = $name;
return true;
}

The problem now is that there is no place we can put them without using Horizontal Reuse,
apart from copying and pasting different bits of code or resorting to using conditional
inheritance. This is where Traits come to the rescue; let's start off by wrapping these
methods in a Trait called Name:
trait Name
{
function setFirstName(string $name): bool
{
$this->firstName = $name;
return true;
}

function setLastName(string $name): bool


{
$this->lastName = $name;
return true;
}
}

So now that we've defined our Trait, we can just tell PHP to use it in our Cat class:
class Cat extends Animal
{
use Name;

public function walk()


{
return "walking with tail wagging...";

[ 17 ]
Why "Good PHP Developer" Isnt an Oxymoron

}
}

Notice the use of the Name statement? That's where the magic happens. Now you can call
the functions in that Trait without any problems:
$whiskers = new Cat();
$whiskers->setFirstName('Paul');
echo $whiskers->firstName;

All put together, the new code block looks as follows:


trait Name
{
function setFirstName(string $name): bool
{
$this->firstName = $name;
return true;
}

function setLastName(string $name): bool


{
$this->lastName = $name;
return true;
}
}

class Animal
{
public function walk()
{
return "walking...";
}
}

class Cat extends Animal


{
use Name;

public function walk()


{
return "walking with tail wagging...";
}
}

$whiskers = new Cat();


$whiskers->setFirstName('Paul');
echo $whiskers->firstName;

[ 18 ]
Another Random Scribd Document
with Unrelated Content
and how singularly it had been preserved in the midst of unheard-of
perils. Mrs. Desborough's eyes were welling over as she thought of
her long-lost darling, in the midst of the wild beasts in a trackless
koond, yet fed and cherished! How?
By the mercy of our heavenly Father, as she truly said, in the
fervour of her mother's love. But she did not see the way in which
the wonderful escape had been brought about. She knew nothing of
the double nature in the wolf; and they told her it was safe in
Rattam's cage. That there was any danger yet for her child, from the
very love of the wolves, never crossed her mind; how could it?
She had enough to think about. Her child was at her feet, but it
had forgotten its home. She saw it, estranged and wild.
"Call him by his name," said Mr. Desborough. "Call him Carl
every time you give him anything to eat, and he will remember his
name; if not, he will soon learn it afresh. We must 'gentle' him, as
the grooms say, my dear. Never fear; we shall bring him round."
Carl had taken the wing of the chicken Kathleen had brought
him, and laid his other bone on the floor. Kathleen still sat on the
carpet by his side, with a patience she had never shown to any one
before. He had even rubbed his head against her shoulder, when the
moongus, which had been asleep in one corner of the room,
aroused, and seeing an inviting bone, stole up to it for a taste. Carl
flew at it in savage fury, tearing and raging. The scuffle which
ensued before the two were parted filled Mrs. Desborough with
many fears for Horace, who was happily in bed and asleep before his
brother was brought home. But to the surprise of every one present,
when Mr. Desborough made his voice heard above the din of the
combatants, Carl was silent in a moment, and dropped back on the
floor in instantaneous obedience. After a little while he came
creeping to his father's feet. Oh, it was piteous to see him so, and
yet it was hopeful.
Kathleen, who was trembling all over, put her moongus out of
the room, and ran back with her lap full of playthings. She had
brought Carl's own old drum that he used to be so fond of, and his
horse and cart, and a new steam-engine he had never seen.
"Perhaps," she thought, "he may remember these. They were his
favourites; and Racy always loves my engine." She set it running on
the floor before Carl's feet. The major lifted up his corner of the
tablecloth, that he might watch the proceedings. Carl gave one of
his frog-like leaps, pounced on the swiftly-moving toy, and snapped
it in two with a cry of delight.
"Never mind, dear," said Mrs. Desborough, turning to Kathleen.
"Mind, mamma!" repeated Kathleen desperately; "can I ever
mind anything he does, when I know that all this happened because
I meddled with the blind? You told me never to touch it, and all my
crying would not undo the mischief. Carl is better than I am,
mamma, for he has minded every word papa has spoken."
"This comforts me, Kathleen, more than anything else,"
answered her mother fondly. "Always to obey is the one great lesson
for every child to learn, and it cannot be learned too early. It is the
foundation-stone of all that is good in after life—a young child's
safeguard and its shield. If you both are careful to obey, we shall
soon bring Carly round, and all be happy again."
Kathleen hung her head in her self-reproachful shame. She did
not see the joy in her mother's eyes; for there is no joy so dear to a
mother's heart as the joy of seeing her children try to overcome
their faults, and turn to all that is right and good.
No one else understood the whispered conversation; they were
all intent on Carl. Oliver took up the drum and beat a jolly tune.
Suddenly Carl sprang up and listened. Yes, there was a tiny
creeping sound. It was only the lizard from behind the picture-frame
that hung over the sideboard coming out for its crumbs, which
Kathleen gathered for it every day after dinner. It was a pretty rose-
pink creature, with a sharply-pointed tail and bead-like eyes. It had
grown so tame it ran between the plates, helping itself as it liked.
"Tic-tickee!" cried Carl, calling it by the Hindu name his ayah
had taught him, and grabbing at it with both his hands.
Strange that he should remember the lizard, when everything
else was forgotten! Had he played with the lizards in the forest? Oh,
horror! he was going to eat it. Bona nearly screamed. In her heart
she was almost as afraid of him as the Hindu servants, and was
thankful when the deputy talked of going, for the storm was over.
"If you want us, Desborough," said Major Iffley, "we are not so
very far away. But you will tame your young savage all the better
when you are alone."
They were careful even in the moment of departure not to leave
a door ajar, for fear little Carl should try to rush out.
"Come and look at him to-morrow," replied Mr. Desborough,
"when a warm bath and his mother's scissors have had their turn."
"Leave the shoes and socks for a day or two—that is my
advice," laughed the deputy as he rode away, splashing through the
flood that still surrounded the compound.
The horse which had been found for Oliver was tired with its
day's hard work, and would not keep pace with his uncle's and
Bona's. As he lagged behind he heard a cow lowing in the
moonlight. He thought of the Thibetan when he saw the horned
head drinking at the stream which drained the road. He rode up to
it, looking for the scarlet necklet she had described.
There it was, embroidered all over with tiny shells in a most
fanciful pattern. Laughing heartily to think of so much ingenuity
being wasted on a cow, he drove it before him into the gates of
Runnangore, glad to have recovered one of the scattered herd for
their luckless owner. He was sure that Mr. Desborough would look
after her; but he meant to take her a new blanket all the same.

CHAPTER XVI.
THE CONCLUSION.

The sunrise found Old Gray Legs roaming through the koond in
search of his missing mate, whilst the half-grown wolflings sat
howling by the korinda bush until the sun was high. The time for
sleep had come. They laid themselves down, but not to rest. The
most adventurous of them all had his ear on the ground listening. It
heard Old Gray Legs give tongue as he found himself at last on the
track of his mate. Out they all rushed, scattering themselves over
bush and boulder to join him. They were scenting the ground as
they ran, and one of them alighted on the path which Carl had taken
with his furry protector. Once on the scent of his lost playfellow, the
keen young wolf pursued him through all its windings to the pit,
which it had just light enough to avoid, then up to the heights, and
back to the very gate of Mr. Desborough's compound, where it lay
crouching among the ferns.
The native servants were at their usual work. Bene Madho was
returning from the bazaar, with one or two of the coolies carrying
home his purchases. The dandy-bearers, who went into the patches
of jungle to cut grass for the horses every day, were coming back
with their bundles on their heads. The Thibetan was with them. She
had gone out hoping to see something of her straying cattle. Oliver,
too, had risen early. He wanted to tell her to come over to
Runnangore and claim her cow. In spite of her rags and her losses
she was a rich woman. She had only to sell a few of her beads to
buy a new herd. Bona would gladly become their purchaser, so he
made this a reason for presenting himself at the gate of Noak-holly
by five o'clock in the morning. He did not expect to see either Mr. or
Mrs. Desborough at such an hour, but he thought he might inquire of
the servants how the night had gone.
In truth, it had gone queerly enough behind the nursery purdah,
where both father and mother had been working at their precious
little savage with sponge, soap, and towel. The cutting of his hair
was terrible, and, worse than all, the cutting of his nails, which had
grown into veritable claws. The poor wee child, so long a stranger to
bath or hair-brush, hated both. If his father had not been there to
hold him, it would not have been possible to wash him clean from
Tara's bird-lime. Painful as the tedious process must have been, he
was singularly obedient. He seemed to like nothing so well as coiling
himself round on his mother's lap. But to get him to sleep was an
impossibility. Oh how his father longed for the lulling influences of
the water-shed on the hills! Carl was continually racing after the
toads and spiders, making all sorts of strange noises, feeling his way
about the darkened room, and howling at each unfamiliar sound. But
morning dawned, and he began to yawn and blink in the growing
light. Suddenly he gave one of his frog-like leaps, parting the chintz
curtains of the purdah with his head, and peeping into the veranda.
Mr. Desborough was nodding; but mamma was close beside her boy,
wondering what he would do next. The servants were all astir, and
the gate was locked, so she let him take his first look round by
daylight.
Another bound and he was over the veranda railing into the
garden, where he coiled himself round in the middle of a bed of
mignonnette, and settled for sleep at last.
"Better not disturb him," thought Mrs. Desborough. "After so
many months in the woods he could not sleep indoors."
So she opened a large white sunshade over his head, and sat
down under an acacia tree to watch his slumbers.
Mr. Desborough was sleeping too, having had no rest for two
whole nights. She could not bear to wake him, so she called up
Kathleen. It was early; but the early morning in India is delightful.
The ayah brought her, and returned to Horace, who had not yet
seen his brother.
Swarms of young frogs had appeared in the veranda after last
night's storm. The bhisti was gathering them up, sweeping them into
a pail to carry away and put them somewhere outside the
compound. Kathleen amused herself with watching the round, red
insects which covered the grass, looking as if, instead of a hailstorm,
there had been a shower of red velvet buttons, the rain had brought
them out in such numbers. The gardener was hoeing within call.
"Yes," thought Mrs. Desborough; "all safe at home. All danger
over now." Yet she could not take her eyes off the little sleeper in
the mignonnette.
"When he awakens," she said to Kathleen, "we will let him see
Horace at play in the veranda. I fear they have forgotten each other;
but they are twins, and the old love will revive. It will be safer to
have the veranda railing between them at first. Racy is so trying,
and if Carl grew cross he might fly at his brother as he did at your
moongus. We will put the old red reins on Carl, so that he cannot
leap away unawares. Being with Racy will bring Carl round sooner
than anything else, if it is but safe to let them be together."
Whilst Mrs. Desborough was speaking the men came in with
their bundles of grass. As the gate opened, in rushed the wolf with a
cry. Up flew Carl with a bound of delight to meet it. They tumbled on
the grass together in a tumult of ecstasy. Mrs. Desborough's first
thought was to lift up Kathleen into the acacia under which they
were sitting, while she shrieked for help. At the sound of her voice
and of the running feet hurrying towards her from every direction,
the wolf stopped in its gambols, seized Carl in its mouth, and was
dragging him away. They were nearly at the gate.
"Come back, Carl! Carl, come back!" cried Kathleen from the
acacia boughs.
Mr. Desborough ran out with his gun. He was levelling it to take
deadly aim, when he perceived the close embrace with which Carl
was clinging to the wolf, and lowered it in despair.
"Shut the gate!" he shouted.
Oliver and the Thibetan rushed into the garden.
Mrs. Desborough saw Carl turn his head at the sound of his
sister's voice, and she repeated the call in her desperation. His name
rang loud and clear above the clamour the servants were raising in
their usual fashion. Carl came as a well-trained dog obeys his
master, and, O horror! the young wolf with him. She showered the
cakes she had brought with her across the grass towards him. Oliver
snatched a pitchfork from one of the grass-cutters and ran; but the
Thibetan, who was the nearest, seized the wolf by the hind legs and
held it fast. Oliver put the arching tines of the pitchfork over its neck
like a collar, and drove the points into the ground until its head was
fixed but not hurt, and he leaned on the handle with all his strength
to keep it there. Oh for Tara Ghur! but the old shikaree was far
away, rejoicing in his well-deserved and ample reward. Was there
nobody to help?
"Hold hard!" shouted Mr. Desborough, as he rushed up white
and resolute to pull the child away. But Carl clung passionately to his
furry playfellow. The wolf had ceased to struggle, but it held his
pinafore in a grip of iron.
Mr. Desborough tore the thin muslin in two, and forced the child
backwards. Mrs. Desborough was close beside him. She pushed the
sweetest cake she had into Carl's mouth to try to divert his
attention. He threw it to the wolf as he struggled to free himself
from his father's arm.
"Booraba no hurt child," said the Thibetan, who had watched
the wolf and the child all night in the shikaree's pit. "Young booraba
like its bahee [brother]. Hurt it, and child hate you all its life. Cage it,
child stop, feed booraba; no run away from each other."
There was so much sense in what she urged so earnestly, Mr.
Desborough was afraid to disregard it. He looked around him, not
knowing what to do for the best. Then he shouted to the grass-
cutters to fetch the iron hurdles which divided the paddock behind
the garden. They ran across, pulled them up, and flung them over
the hedge of roses.
Meanwhile Bene Madho had fetched old Gobur to the sahib's
assistance. Mrs. Desborough had taken off Kathleen's sash and
knotted it round Carl's waist, so that she could hold him whilst Mr.
Desborough fixed the hurdles firmly in the grass.
Gobur came up with another pitchfork and put it over the wolf's
hind legs, fixing them to the ground, as Oliver had fixed its head, to
release the courageous Thibetan. It was a trying moment for Oliver
when Mr. Desborough put down the fourth hurdle and shut him in
with the wolf and Gobur. It was a tremendous effort to hold the wolf
down, and he was getting exhausted.
Mr. Desborough saw this, and leaving his men to make a
threefold fence round the wolf, he leaned over the hurdle and took
the handle of the pitchfork from him. The boldest of the syces
followed his example, and released Gobur. It was a moment of
intense relief to Mrs. Desborough when she saw them both safely
outside. The Thibetan was helping her to control Carl, who was
struggling to get free. Five or six men were driving in the hurdles as
fast as they could, and in the noise of their hammering Mrs.
Desborough could no longer make herself heard.
By Mr. Desborough's orders every hurdle on the place was
brought, until a perfect pyramid of iron was piled over the prostrate
wolf. After the three-fold fence a row of hurdles were set endways
between the lines, slanting inwards, and over these another tier was
laid to form a roof, and another and another, crossing each other in
every direction. Before the last corners were shut in the pitchforks
were slowly withdrawn, and young Fawnie was left unhurt to
examine the iron house which had been built over him.
One hurdle at the top was so placed that it could be withdrawn
a little way, like a window-shutter. Gobur climbed up and let down a
pail of water.
All the while the men were at work, Carl and the wolfling were
crying to each other.
The wolfling was not yet six months old, and had not learned to
be so wary as its mother. Yet it was strangely quieted when it found
itself a prisoner. Not so Carl: he stamped, and sobbed, and kicked in
an agony of distress, because he was shut out.
"Give him his liberty," said Mr. Desborough. "Let him run up to it
if he likes."
Carl flew to the hurdles and tried to push between their rails,
whilst Fawnie, as Oliver called the wolfling, worked at them from the
inside. But the iron walls of his prison were too firmly built to be
shaken. A frog leaped out of the grass. Fawnie snapped it up, and
brought it to give to Carl through his prison bars.
Then Mrs. Desborough realized how her darling had been fed
and kept alive in the trackless jungle.
Oliver was telling her of the old gray wolf now in Rattam's cage,
and the Thibetan repeated her story.
The mother's feelings can be better imagined than described
when she saw thus clearly that the love of the wild wolves had
saved her child. Could she doubt it?
"Ought we to think it impossible?" urged Oliver. "In spite of all
its savagery, the dog's nature is in the wolf. It is the strong family
feeling amongst them which makes the pack. You see, I have heard
a great deal about them from Tara Ghur; and I shall never forget
that old wolf's face as she turned to Carl in the pit."
Gobur and the gardener were cutting off some long branches
from the nearest trees, to thatch poor Fawnie's pyramid and shelter
him from the sun.
Oliver ran to help them, until Fawnie's den looked like a gigantic
heap of boughs. Then Oliver fetched the gardener's syringe and
drenched it.
When Fawnie found it growing dark and cool as the nest
beneath the korinda bush, he laid himself down and fell into the
sound mid-day sleep of the wild beast.
But nothing short of force could drag Carl away, and that was
not to be thought of. Mr. Desborough saw it would only embitter the
child, and rouse and exasperate the wolfling. He was hoping that if
Carl were left to himself he too would fall asleep. But no; all sleep
was gone. Carl kept on raging round and round the pyramid, tugging
with all his might at the boughs which hid his furry friend.
Mr. Desborough lifted Kathleen down from the acacia. Her
presence had helped him so much in getting Carl safely through his
journey home. But her brave little heart was failing her; she had
been terribly frightened at the sight of Fawnie, and she clung to her
mother, trembling.
"Fetch Racy," said Mr. Desborough in despair. "The sight of his
twin-brother may draw the child away. We must try something."
Mrs. Desborough went herself, not daring to trust any one else
with the rebellious Racy in such circumstances.
She soon reappeared, driving him before her on his pretty
bicycle-horse; while the ayah crept beside her, her black face
puckered with anxiety and fear as she looked at the group on the
lawn, and above all at the portentous pyramid.
Horace, who could not understand what had happened,
flourished his whip and shouted to his heart's content. He was highly
delighted at having got mamma to be his syce. She slowly drove him
round the lawn. Of course, he wanted to gallop off at once to his
father and Kathleen; but Mrs. Desborough turned him back, so that
Carl might see him. The twins perceived each other at last, and drew
together, staring.
"Look, Racy, who is that sitting on the grass? Can it be Carl—
Racy's own lost Carl—come home at last?"
Carl's eyes followed every movement of the pretty brown horse
with a strange bewilderment.
Kathleen, with her father's arm round her, felt her courage
revive. She glanced up at him inquiringly. He nodded. Away she ran
to meet the young equestrian, calling Carl to follow. Again he
obeyed.
"O Racy!" she exclaimed, "we've found poor Carl. Let us put him
on your horse, and you and I will drive him home, for fear we should
lose him. You push, and I will hold him on. Quick, dear, quick!"
"God bless her," said Mr. Desborough; "she has done it again."
Racy tumbled out of his saddle. Mrs. Desborough and the ayah
lifted Carl into his place. He made no resistance, but laid his face
down and began to bite the horse's ears. Kathleen seized the bridle.
Racy pushed manfully behind. Mrs. Desborough held one arm and
the ayah the other. Up ran the bhisti, who stretched over Horace's
head and lifted the horse and its rider right up the veranda steps. As
usual, the hall door stood wide; in rode Carl, and Mrs. Desborough
locked it behind him.
"What is up now?" exclaimed Major Iffley, as he stopped at the
familiar gate. "You have found out something wrong about the
place?"
"Yes, an imperative necessity to leave it. I want to make over
the indigo factory to you for at least a twelvemonth, whilst I take
holiday with my wife and children. We should never have rescued
Carl if he had not learned to obey, and now distance is our best
defence," said Mr. Desborough gravely.
"Done!" answered the major gaily.
"If you go," put in Oliver earnestly, "give Fawnie over to me. He
is young enough to tame and train, and I should be proud to own
him. With a stout chain and collar he will prove a noble dog."

THE END.

*** END OF THIS PROJECT GUTENBERG EBOOK ALIVE IN THE


JUNGLE ***
*** END OF THE PROJECT GUTENBERG EBOOK ALIVE IN THE
JUNGLE: A STORY FOR THE YOUNG ***

Updated editions will replace the previous one—the old editions


will be renamed.

Creating the works from print editions not protected by U.S.


copyright law means that no one owns a United States
copyright in these works, so the Foundation (and you!) can copy
and distribute it in the United States without permission and
without paying copyright royalties. Special rules, set forth in the
General Terms of Use part of this license, apply to copying and
distributing Project Gutenberg™ electronic works to protect the
PROJECT GUTENBERG™ concept and trademark. Project
Gutenberg is a registered trademark, and may not be used if
you charge for an eBook, except by following the terms of the
trademark license, including paying royalties for use of the
Project Gutenberg trademark. If you do not charge anything for
copies of this eBook, complying with the trademark license is
very easy. You may use this eBook for nearly any purpose such
as creation of derivative works, reports, performances and
research. Project Gutenberg eBooks may be modified and
printed and given away—you may do practically ANYTHING in
the United States with eBooks not protected by U.S. copyright
law. Redistribution is subject to the trademark license, especially
commercial redistribution.

START: FULL LICENSE


THE FULL PROJECT GUTENBERG LICENSE
PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK

To protect the Project Gutenberg™ mission of promoting the


free distribution of electronic works, by using or distributing this
work (or any other work associated in any way with the phrase
“Project Gutenberg”), you agree to comply with all the terms of
the Full Project Gutenberg™ License available with this file or
online at www.gutenberg.org/license.

Section 1. General Terms of Use and


Redistributing Project Gutenberg™
electronic works
1.A. By reading or using any part of this Project Gutenberg™
electronic work, you indicate that you have read, understand,
agree to and accept all the terms of this license and intellectual
property (trademark/copyright) agreement. If you do not agree
to abide by all the terms of this agreement, you must cease
using and return or destroy all copies of Project Gutenberg™
electronic works in your possession. If you paid a fee for
obtaining a copy of or access to a Project Gutenberg™
electronic work and you do not agree to be bound by the terms
of this agreement, you may obtain a refund from the person or
entity to whom you paid the fee as set forth in paragraph 1.E.8.

1.B. “Project Gutenberg” is a registered trademark. It may only


be used on or associated in any way with an electronic work by
people who agree to be bound by the terms of this agreement.
There are a few things that you can do with most Project
Gutenberg™ electronic works even without complying with the
full terms of this agreement. See paragraph 1.C below. There
are a lot of things you can do with Project Gutenberg™
electronic works if you follow the terms of this agreement and
help preserve free future access to Project Gutenberg™
electronic works. See paragraph 1.E below.
1.C. The Project Gutenberg Literary Archive Foundation (“the
Foundation” or PGLAF), owns a compilation copyright in the
collection of Project Gutenberg™ electronic works. Nearly all the
individual works in the collection are in the public domain in the
United States. If an individual work is unprotected by copyright
law in the United States and you are located in the United
States, we do not claim a right to prevent you from copying,
distributing, performing, displaying or creating derivative works
based on the work as long as all references to Project
Gutenberg are removed. Of course, we hope that you will
support the Project Gutenberg™ mission of promoting free
access to electronic works by freely sharing Project Gutenberg™
works in compliance with the terms of this agreement for
keeping the Project Gutenberg™ name associated with the
work. You can easily comply with the terms of this agreement
by keeping this work in the same format with its attached full
Project Gutenberg™ License when you share it without charge
with others.

1.D. The copyright laws of the place where you are located also
govern what you can do with this work. Copyright laws in most
countries are in a constant state of change. If you are outside
the United States, check the laws of your country in addition to
the terms of this agreement before downloading, copying,
displaying, performing, distributing or creating derivative works
based on this work or any other Project Gutenberg™ work. The
Foundation makes no representations concerning the copyright
status of any work in any country other than the United States.

1.E. Unless you have removed all references to Project


Gutenberg:

1.E.1. The following sentence, with active links to, or other


immediate access to, the full Project Gutenberg™ License must
appear prominently whenever any copy of a Project
Gutenberg™ work (any work on which the phrase “Project
Gutenberg” appears, or with which the phrase “Project
Gutenberg” is associated) is accessed, displayed, performed,
viewed, copied or distributed:

This eBook is for the use of anyone anywhere in


the United States and most other parts of the
world at no cost and with almost no restrictions
whatsoever. You may copy it, give it away or re-
use it under the terms of the Project Gutenberg
License included with this eBook or online at
www.gutenberg.org. If you are not located in the
United States, you will have to check the laws of
the country where you are located before using
this eBook.

1.E.2. If an individual Project Gutenberg™ electronic work is


derived from texts not protected by U.S. copyright law (does not
contain a notice indicating that it is posted with permission of
the copyright holder), the work can be copied and distributed to
anyone in the United States without paying any fees or charges.
If you are redistributing or providing access to a work with the
phrase “Project Gutenberg” associated with or appearing on the
work, you must comply either with the requirements of
paragraphs 1.E.1 through 1.E.7 or obtain permission for the use
of the work and the Project Gutenberg™ trademark as set forth
in paragraphs 1.E.8 or 1.E.9.

1.E.3. If an individual Project Gutenberg™ electronic work is


posted with the permission of the copyright holder, your use and
distribution must comply with both paragraphs 1.E.1 through
1.E.7 and any additional terms imposed by the copyright holder.
Additional terms will be linked to the Project Gutenberg™
License for all works posted with the permission of the copyright
holder found at the beginning of this work.
1.E.4. Do not unlink or detach or remove the full Project
Gutenberg™ License terms from this work, or any files
containing a part of this work or any other work associated with
Project Gutenberg™.

1.E.5. Do not copy, display, perform, distribute or redistribute


this electronic work, or any part of this electronic work, without
prominently displaying the sentence set forth in paragraph 1.E.1
with active links or immediate access to the full terms of the
Project Gutenberg™ License.

1.E.6. You may convert to and distribute this work in any binary,
compressed, marked up, nonproprietary or proprietary form,
including any word processing or hypertext form. However, if
you provide access to or distribute copies of a Project
Gutenberg™ work in a format other than “Plain Vanilla ASCII” or
other format used in the official version posted on the official
Project Gutenberg™ website (www.gutenberg.org), you must,
at no additional cost, fee or expense to the user, provide a copy,
a means of exporting a copy, or a means of obtaining a copy
upon request, of the work in its original “Plain Vanilla ASCII” or
other form. Any alternate format must include the full Project
Gutenberg™ License as specified in paragraph 1.E.1.

1.E.7. Do not charge a fee for access to, viewing, displaying,


performing, copying or distributing any Project Gutenberg™
works unless you comply with paragraph 1.E.8 or 1.E.9.

1.E.8. You may charge a reasonable fee for copies of or


providing access to or distributing Project Gutenberg™
electronic works provided that:

• You pay a royalty fee of 20% of the gross profits you derive
from the use of Project Gutenberg™ works calculated using the
method you already use to calculate your applicable taxes. The
fee is owed to the owner of the Project Gutenberg™ trademark,
but he has agreed to donate royalties under this paragraph to
the Project Gutenberg Literary Archive Foundation. Royalty
payments must be paid within 60 days following each date on
which you prepare (or are legally required to prepare) your
periodic tax returns. Royalty payments should be clearly marked
as such and sent to the Project Gutenberg Literary Archive
Foundation at the address specified in Section 4, “Information
about donations to the Project Gutenberg Literary Archive
Foundation.”

• You provide a full refund of any money paid by a user who


notifies you in writing (or by e-mail) within 30 days of receipt
that s/he does not agree to the terms of the full Project
Gutenberg™ License. You must require such a user to return or
destroy all copies of the works possessed in a physical medium
and discontinue all use of and all access to other copies of
Project Gutenberg™ works.

• You provide, in accordance with paragraph 1.F.3, a full refund of


any money paid for a work or a replacement copy, if a defect in
the electronic work is discovered and reported to you within 90
days of receipt of the work.

• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.

1.E.9. If you wish to charge a fee or distribute a Project


Gutenberg™ electronic work or group of works on different
terms than are set forth in this agreement, you must obtain
permission in writing from the Project Gutenberg Literary
Archive Foundation, the manager of the Project Gutenberg™
trademark. Contact the Foundation as set forth in Section 3
below.

1.F.
1.F.1. Project Gutenberg volunteers and employees expend
considerable effort to identify, do copyright research on,
transcribe and proofread works not protected by U.S. copyright
law in creating the Project Gutenberg™ collection. Despite these
efforts, Project Gutenberg™ electronic works, and the medium
on which they may be stored, may contain “Defects,” such as,
but not limited to, incomplete, inaccurate or corrupt data,
transcription errors, a copyright or other intellectual property
infringement, a defective or damaged disk or other medium, a
computer virus, or computer codes that damage or cannot be
read by your equipment.

1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except


for the “Right of Replacement or Refund” described in
paragraph 1.F.3, the Project Gutenberg Literary Archive
Foundation, the owner of the Project Gutenberg™ trademark,
and any other party distributing a Project Gutenberg™ electronic
work under this agreement, disclaim all liability to you for
damages, costs and expenses, including legal fees. YOU AGREE
THAT YOU HAVE NO REMEDIES FOR NEGLIGENCE, STRICT
LIABILITY, BREACH OF WARRANTY OR BREACH OF CONTRACT
EXCEPT THOSE PROVIDED IN PARAGRAPH 1.F.3. YOU AGREE
THAT THE FOUNDATION, THE TRADEMARK OWNER, AND ANY
DISTRIBUTOR UNDER THIS AGREEMENT WILL NOT BE LIABLE
TO YOU FOR ACTUAL, DIRECT, INDIRECT, CONSEQUENTIAL,
PUNITIVE OR INCIDENTAL DAMAGES EVEN IF YOU GIVE
NOTICE OF THE POSSIBILITY OF SUCH DAMAGE.

1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you


discover a defect in this electronic work within 90 days of
receiving it, you can receive a refund of the money (if any) you
paid for it by sending a written explanation to the person you
received the work from. If you received the work on a physical
medium, you must return the medium with your written
explanation. The person or entity that provided you with the
defective work may elect to provide a replacement copy in lieu
of a refund. If you received the work electronically, the person
or entity providing it to you may choose to give you a second
opportunity to receive the work electronically in lieu of a refund.
If the second copy is also defective, you may demand a refund
in writing without further opportunities to fix the problem.

1.F.4. Except for the limited right of replacement or refund set


forth in paragraph 1.F.3, this work is provided to you ‘AS-IS’,
WITH NO OTHER WARRANTIES OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR ANY PURPOSE.

1.F.5. Some states do not allow disclaimers of certain implied


warranties or the exclusion or limitation of certain types of
damages. If any disclaimer or limitation set forth in this
agreement violates the law of the state applicable to this
agreement, the agreement shall be interpreted to make the
maximum disclaimer or limitation permitted by the applicable
state law. The invalidity or unenforceability of any provision of
this agreement shall not void the remaining provisions.

1.F.6. INDEMNITY - You agree to indemnify and hold the


Foundation, the trademark owner, any agent or employee of the
Foundation, anyone providing copies of Project Gutenberg™
electronic works in accordance with this agreement, and any
volunteers associated with the production, promotion and
distribution of Project Gutenberg™ electronic works, harmless
from all liability, costs and expenses, including legal fees, that
arise directly or indirectly from any of the following which you
do or cause to occur: (a) distribution of this or any Project
Gutenberg™ work, (b) alteration, modification, or additions or
deletions to any Project Gutenberg™ work, and (c) any Defect
you cause.
Section 2. Information about the Mission
of Project Gutenberg™
Project Gutenberg™ is synonymous with the free distribution of
electronic works in formats readable by the widest variety of
computers including obsolete, old, middle-aged and new
computers. It exists because of the efforts of hundreds of
volunteers and donations from people in all walks of life.

Volunteers and financial support to provide volunteers with the


assistance they need are critical to reaching Project
Gutenberg™’s goals and ensuring that the Project Gutenberg™
collection will remain freely available for generations to come. In
2001, the Project Gutenberg Literary Archive Foundation was
created to provide a secure and permanent future for Project
Gutenberg™ and future generations. To learn more about the
Project Gutenberg Literary Archive Foundation and how your
efforts and donations can help, see Sections 3 and 4 and the
Foundation information page at www.gutenberg.org.

Section 3. Information about the Project


Gutenberg Literary Archive Foundation
The Project Gutenberg Literary Archive Foundation is a non-
profit 501(c)(3) educational corporation organized under the
laws of the state of Mississippi and granted tax exempt status
by the Internal Revenue Service. The Foundation’s EIN or
federal tax identification number is 64-6221541. Contributions
to the Project Gutenberg Literary Archive Foundation are tax
deductible to the full extent permitted by U.S. federal laws and
your state’s laws.

The Foundation’s business office is located at 809 North 1500


West, Salt Lake City, UT 84116, (801) 596-1887. Email contact
links and up to date contact information can be found at the
Foundation’s website and official page at
www.gutenberg.org/contact

Section 4. Information about Donations to


the Project Gutenberg Literary Archive
Foundation
Project Gutenberg™ depends upon and cannot survive without
widespread public support and donations to carry out its mission
of increasing the number of public domain and licensed works
that can be freely distributed in machine-readable form
accessible by the widest array of equipment including outdated
equipment. Many small donations ($1 to $5,000) are particularly
important to maintaining tax exempt status with the IRS.

The Foundation is committed to complying with the laws


regulating charities and charitable donations in all 50 states of
the United States. Compliance requirements are not uniform
and it takes a considerable effort, much paperwork and many
fees to meet and keep up with these requirements. We do not
solicit donations in locations where we have not received written
confirmation of compliance. To SEND DONATIONS or determine
the status of compliance for any particular state visit
www.gutenberg.org/donate.

While we cannot and do not solicit contributions from states


where we have not met the solicitation requirements, we know
of no prohibition against accepting unsolicited donations from
donors in such states who approach us with offers to donate.

International donations are gratefully accepted, but we cannot


make any statements concerning tax treatment of donations
received from outside the United States. U.S. laws alone swamp
our small staff.
Please check the Project Gutenberg web pages for current
donation methods and addresses. Donations are accepted in a
number of other ways including checks, online payments and
credit card donations. To donate, please visit:
www.gutenberg.org/donate.

Section 5. General Information About


Project Gutenberg™ electronic works
Professor Michael S. Hart was the originator of the Project
Gutenberg™ concept of a library of electronic works that could
be freely shared with anyone. For forty years, he produced and
distributed Project Gutenberg™ eBooks with only a loose
network of volunteer support.

Project Gutenberg™ eBooks are often created from several


printed editions, all of which are confirmed as not protected by
copyright in the U.S. unless a copyright notice is included. Thus,
we do not necessarily keep eBooks in compliance with any
particular paper edition.

Most people start at our website which has the main PG search
facility: www.gutenberg.org.

This website includes information about Project Gutenberg™,


including how to make donations to the Project Gutenberg
Literary Archive Foundation, how to help produce our new
eBooks, and how to subscribe to our email newsletter to hear
about new eBooks.
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

textbookfull.com

You might also like