In the world of PHP programming a set of trends are massively being propagated by some people (in their books and on websites) as “Modern PHP” while all other approaches are frowned upon as backwards, stupid, or just plain wrong.
These people seem to work tirelessly at getting other people to follow their way of doing things.
This website has been created in an attempt to present a pragmatic view on PHP programming. A view dictated by experience and practical consequence rather than popular trends, theory, or academic dogma.
The website PHP - The Wrong Way is a living document and will continue to be updated with more information as it become available.
Feel free to contribute.
One problem with programming rules and guidelines is that they often only serve a purpose within a specific context. Taken out of context a good rule can become a horrible rule. In fact, every good rule becomes bad when taken to the extreme.
This is important to understand because many of the software development principles and rules developed over time and presented by many different people often become misused in the hands of extremists.
Experience has taught that misuse of general rules and guidelines always result in complication, lack of security, error prone results, and in some cases complete and utter disaster.
The KISS principle, which is an acronym for “Keep It Simple, Stupid”, is an extremely wise and good principle that is generally viewed by experienced people as a very good advice to follow, but even this great principle becomes a danger to a project if taken to the extreme. There is such a thing as “too simple” resulting in a lack of needed functionality.
The wrong way: Religious following of rules and guidelines.
All general purpose PHP frameworks suck!
– Rasmus Lerdorf
In the PHP community a really bad trend has become de-facto standard for developing web applications and that is by the usage of a popular general purpose framework.
This trend has not emerged and become popular because it in any way improve the result of the developing process, or because it is the right thing to do from a technology and architectural point of view. This trend has become popular because some of the developers of frameworks has managed to sweep away the masses with their polemic against programming from the ground up with stanzas like “Don’t re-invent the wheel!” and “Don’t do it yourself, others are more skillful than you”.
Many of todays programmers completely ignore the fundamental principles of sound programming and they spend huge amount of time fantasying new layers of complexity in order to appear more clever, more cool, and more acceptable by whomever they regard as their peers.
These people seems to be infatuated by the though of having other people follow their “way of doing things”, becoming some kind of PHP community leaders, and having other people use their latest “hip” Open Source tools, that they forget to make sure that the advice they are giving is sound and solid.
In the software industry you can compare a pre-built house to a general purpose framework. Building software using general purpose frameworks doesn’t make you a coder or a programmer any more than putting together a pre-built house makes you a carpenter.
On this website we differentiate between frameworks and libraries in the following way:
- A library is considered a collection of reusable code, like the C standard library, or the Go standard library. It consists of code that you easily integrate into your own projects without enforcing any limitations or restrictions what so ever. It consists of small pieces of code with one specific functionality each.
- A framework is not just a collection of reusable code, you cannot simply take a piece of code from the framework and integrate it into your own project. A framework is a system that helps you build software, but at the same time it forces you to work within the limitations and restrictions of the framework itself. The framework itself has lot of interdependent functionality. One piece cannot work without the other.
In the world of Python and Ruby building websites from the ground up is tiresome because neither Python nor Ruby was originally created to build websites. As a result general purpose frameworks such as Django and Ruby on Rails quickly became popular for building websites in these languages.
PHP on the other hand was created from the beginning by Rasmus Lerdorf as a set of tools written in C that would enable you to easily and quickly develop dynamic HTML. As such PHP was, and still is, a framework in and of itself.
PHP has evolved massively since then and today PHP can be used for much more than building HTML and websites, but viewing PHP as a sort of framework in itself is not wrong. PHP is by nature a layer of abstraction for developing web applications written entirely in a procedural C.
Using a library within your project is only natural. PHP itself comes bundled with a set of libraries that you can use to extend your own code. PDO for example is a lightweight library that provides a consistent interface for accessing databases in PHP.
Using a framework on top of PHP on the other hand is another matter entirely.
When you use a framework in PHP you add a layer of abstraction on top of yet another layer of abstraction, one that was already in place for you to use to begin with. The added layer of abstraction that the framework provides may simply serve to organize your code into a pre-fixed set of patterns, or it may add even more complexity by intertwining hundreds or even thousands of classes and methods into a nightmare of dependencies, either way you’re adding layers of complexity to your code that isn’t needed!
All experience starts with the interface. The interface experience is the result of the underlying technology and the amount of layers of abstraction. The more abstraction you use, the less efficient the interface becomes and the more error prone the application becomes. The higher abstraction, the more detail and efficiency, is lost.
Understand this clearly: The ideal number of lines of code in any project is as few as possible!
What everyone doesn’t need is a general purpose framework. Nobody has a general problem, everyone has a very specific problem they are trying to solve.
– Rasmus Lerdorf
Some companies began listening to the hype about PHP frameworks and they started their next projects using one of these popular general purpose frameworks only to end up in a disaster. They not only discovered that the general purpose framework was really bad at solving their very specific need, but it was also extremely slow in doing so. It was impossible to scale and as a result they started ripping the framework apart in a desperate attempt to pull out all those things they really didn’t need.
Always use the pragmatic approach:
Action or policy dictated by consideration of the immediate practical consequences rather than by theory or dogma.
– Collins English Dictionary, Complete and Unabridged, 12th Edition 2014
The wrong way: Always use a framework on top of PHP.
I have this big allergy to ivory-tower design and design patterns. Peter Norvig, when he was at Harlequin, he did this paper about how design patterns are really just flaws in your programming language. Get a better programming language. He’s absolutely right. Worshipping patterns and thinking about, “Oh, I’ll use the X pattern.”
– Brendan Eich.
In software engineering, a design pattern is a reusable solution to a commonly occurring problem in software design. A design pattern is not a finished design that can be transformed directly into code. It is a description or an idea for how to solve a problem that can be used in many different situations. Object-oriented design patterns typically show relationships and interactions between classes or objects, without specifying the final application classes or objects that are involved.
PHP supports imperative, functional, object-oriented, procedural, and reflective paradigms. PHP is a huge toolbox with lots of different tools that makes it possible to solve many problems in many different ways - not just one way.
PHP is all about freedom, fast and scalable solutions, and having many different ways to deal with problems.
When we try to improve ourselves, and in this case more specifically our code, we sometimes get hung up in the philosophy of a particular pattern or idea and tend to forget to think practical.
When I see patterns in my programs, I consider it a sign of trouble. The shape of a program should reflect only the problem it needs to solve. Any other regularity in the code is a sign, to me at least, that I’m using abstractions that aren’t powerful enough - often that I’m generating by hand the expansions of some macro that I need to write.
– Paul Graham
We shouldn’t get to caught up in the philosophy or idea behind a specific pattern or solution. Our main concern is to keep the code as easy to navigate and understand as possible and as a result easy to maintain and easy to keep secure.
We must also remember that there exist such a thing as an anti-pattern. It is a pattern that may be commonly used but is ineffective and/or counterproductive in practice.
Paul Weaton, a SUN certified Java programmer, has a great short article about Evil Design Patterns that’s worth reading.
I think patterns started off as generally recognized best solutions for common problems. But now that they have been around for a while and we have experienced applications being made ten times more complicated than they need to be because people try to cram in all the patterns that they have read about (“my application is well architected, because it is loaded to the gills with patterns.”) my impression of the value of the pattern has shifted a bit.
– Paul Weaton
Always use the pragmatic approach:
Action or policy dictated by consideration of the immediate practical consequences rather than by theory or dogma.
– Collins English Dictionary, Complete and Unabridged, 12th Edition 2014
The wrong way: Thinking of patterns when solving problems.
The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.
– Joe Armstrong
Abstraction is powerful. What I’m really allergic to, and what I had a reaction to in the ’90s, was all the CORBA, COM, DCOM, object-oriented nonse. Every startup of the day had some crazy thing that would take 200.000 method calls to start up and print “Hello world”. That’s a travesty! You don’t want to be a programmer associated with that sort of thing.
– Brendan Eich
Many software developers, and many companies, feel that object-oriented programming is the only reasonable way to develop software today. Any one who argues against object-oriented programming is immediately made conscious of the fact that they are arguing against the “conventional wisdom” of the industry.
On programming blogs and forums, there are a great many people who defend object-oriented programming, and who feel certain that they know what they are talking about, despite the lack of any standard definition!
The fact is that so-called object-oriented programming as such often inflict a heavy burden of unneeded complexity!
As computer scientists and programmers we must learn to set aside prejudices and find the best solution to a given problem.
Today one of the main strengths of PHP is it’s support for both imperative, functional, object-oriented, procedural, and reflective paradigms. PHP is a huge toolbox with lots of different tools that makes it possible to solve many problems in many different ways - not just one way!
As soon as we try to force-feed different problems within an application to a single specific programming paradigm, we’re not thinking creatively and we’re not working efficiently!
A small history lesson
One of the greatest ways to understand a specific programming paradigm is to look at how it first evolved. What was the reason for its development? What problems existed with other programming paradigms that needed a new way of thinking? Was it a real world problem or simply an academic problem? And how has it since evolved?
It doesn’t matter what person X says or what definition person Y gives, what matters in the context of paradigms is the history that made them.
There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies.
– C.A.R. Hoare
In the past, before the advent of object-oriented programming, around the end of the fifties, much software was developed using programming languages that emphasized unstructured programming, sometimes are referred to as first- and second-generation languages. Unstructured programming (or non-structured programming) is the historical earliest programming paradigm. It was heavily criticized for producing “spaghetti” code.
There are both high- and low-level programming languages that use non-structured programming. These include early versions of BASIC, COBOL, MUMPS, JOSS, FOCAL, TELCOMP, machine-level code, early assembler systems (those without procedural meta operators) and some scripting languages.
A program in a non-structured language usually consists of sequentially ordered commands, or statements, usually one in each line. The lines are usually numbered or may have labels which allows the flow of execution to jump to any line in the program (like with the unpopular GOTO statement).
Then in the sixties structured programming emerged - mainly due to the famous letter by Edsger W. Dijkstra Go To statements considered harmful.
Structured programming is a programming paradigm that improves the clarity, quality, and development of software by making use of subroutines, block structures and loops. This is contrast to using simple jumps such as the GOTO statement.
Later procedural programming was derived from structured programming. Procedural programming is based upon the concept of “procedure call”. A “procedure call” is just another name for a “function call”. Procedures are also known as routines, subroutines or methods. A procedure simply contain a series of computational steps to be carried out. Any given procedure might be called at any point during a programs execution, including by other procedures or itself.
In the beginning all procedures were available to any part of a program as global data. In small programs this didn’t present a problem, but as things got more complicated and the size of the program grew, small changes to one part of the program greatly effected many other parts.
Nobody was planning for changes in the program and lots of dependencies existed. A minor change to one procedure would result in a cascade of errors in lots of other procedures that depended on the original code.
A new technique evolved which allowed data to be divided into separated scopes called “objects”. Only specific procedures belonging to the same scope could access the same data. This is called data hiding or encapsulation. The result was much better organized code.
In the beginning objects where not called objects, they where just viewed upon as separate scopes. Later when dependencies were reduced and connections between procedures and variables inside these scopes where viewed upon as isolated segments, the result gave birth to the concepts of “objects” and “object-oriented programming”.
Later, mainly due to the development of Java, certain “buzzwords” arose and “a procedure” or “a function” was no longer called a function, but was renamed “a method” when it resided inside a separate scope. Variables was also no longer called “variables”, but was renamed “attributes” when they resided inside a separate scope.
So an object is in essence simply a collection of functions and variables now called “methods and attributes”.
The way methods and attributes are kept isolated inside a separate scope is by the usage of “a class”. A class, once it is instantiated, is called an object.
Objects can reference each other and by such a reference the methods (functions) inside can “communicate” with each other. Objects can also “inherit” methods from other objects thereby extending such, this is called “inheritance”. It is a way to reuse code and allow independent extensions of the software via public classes and interfaces. The relationships of objects give rise to a hierarchy. Inheritance was invented in 1967 for the programming language Simula 67.
Objects can also inherit methods from other objects and “override” these with added or changed functionality, this is called “polymorphism”.
How these different ideas are implemented vary greatly from programming language to programming language.
Object-oriented programming is about organizing code in another way than before. It is an extension of procedural programming and it is about hiding data (encapsulation) and avoiding a global scope. It is about extending functions by “borrowing” their blueprints without actually affecting the original code (inheritance). And it is about overriding functions without affecting the original code (polymorphism).
The object-oriented model makes it easy to build up programs by accretion. What this often means, in practice, is that it provides a structured way to write spaghetti code.
– Paul Graham
The wrong way: Always use object-oriented programming.
The FIG stands for “Framework Interoperability Group”.
The PHP-FIG was created by a number of framework developers at php|tek in 2009. Since then various other members have applied and been voted in, increasing the size of the group from the first 5 to over 20.
A lot of controversy exists regarding the PHP-FIG. Some people consider the PHP-FIG the best thing that has happened to the PHP community since PHP itself while others considers the group as something best be forgotten.
One of the problems with PHP-FIG is that it presents itself like this in their FAQ:
The idea behind the group is for project representatives to talk about the commonalities between our projects and find ways we can work together. Our main audience is each other, but we’re very aware that the rest of the PHP community is watching. If other folks want to adopt what we’re doing they are welcome to do so, but that is not the aim. Nobody in the group wants to tell you, as a programmer, how to build your application.
However, when we view the work of several members of the group we can clearly see that the objective is quite contrary to the above statement. These members work tirelessly in an attempt to make PHP-FIG become an accepted “PHP standards group”, which also was the original name of the group. They do this by classifying the work of the PHP-FIG as “Modern PHP” in their books, on their websites, blog-posts, forums, etc., and by classifying other ways as backwards.
One of the problems with the PHP-FIG is that even though many frameworks and Open Source projects has adopted several of their standards, these standards mainly deal with problems from a “framework perspective” which renders them pretty unusable in many real-life industry situations.
Many people develop software for the industry that has to be extremely efficient, secure, and cost-effective, software that customers are willing to buy and use. They cannot be bothered with standards that has to conform to the needs of framework fanatics. If they tried to be it would be a disaster for business.
If some kind of standards group needs to be created it has to reflect the interests of the entire PHP community, not just framework and Open Source CMS project developers. It has to be represented by the developers of the PHP programming language itself and it has to be represented by a much larger membership with the right to vote.
If you choose to adopt the standards developed by the PHP-FIG, you have to understand that some of these standards - such as the autoloader standards PSR-0 and PSR-4 and several other standards - has a direct effect upon how you code your software.
Many industries demand highly scalable, run-time critical, and cost effective software that simply cannot be developed using these standards of the PHP-FIG.
The wrong way: Following the PHP-FIG beyond the PSR-1 and PSR-2.
The trouble with programmers is that you can never tell what a programmer is doing until it’s too late.
– Seymour Cray
Secure coding is the practice of writing programs that are resistant to attack by malicious or mischievous people or other programs. Secure coding helps protect data from theft or corruption. In addition, an insecure program can provide access for an attacker to take control of a server or a user’s identity, resulting in anything from a denial of service to a single user to the compromise of secrets, loss of service, or damage to the systems of thousands of users.
Every computer program is a potential target for a security attack. Attackers will try to find security vulnerabilities in your applications. They will then try to use these vulnerabilities to steal secrets, corrupt programs and data, and gain control of servers and networks. Your customers property and your reputation are at stake.
Security is not something that can be added to software!
An insecure application may require extensive redesign to secure it. You must identify the nature of the threats to your software and incorporate secure coding practices from the beginning and throughout the planning and development of your application.
Securing critical software resources is more important than ever as the focus of attackers has steadily moved toward the application layer. A 2009 SANS study found that attacks against web applications constitute more than 60% of the total attack attempts observed on the Internet.
PHP is unusual in that it is both a programming language and a web framework at the same time. This means that PHP has a lot of web features build-in to the language that makes it very easy to write insecure code.
Secure by default
Complexity kills. It sucks the life out of developers, it makes products difficult to plan, build and test, it introduces security challenges and it causes end-user and administrator frustration.
– Ray Ozzie
In order for applications to be designed and implemented with proper security requirements, secure coding practices and a focus on security risks must be integrated into the day-to-day operations, thoughts, and the development processes itself.
Generally, it is much less expensive to build secure software than to correct security issues after the software package has been completed, not to mention the costs that may be associated with a security breach.
The wrong way: Not developing secure software by default.
It’s easy to misunderstand a written document so lets clarify some issues.
Q:Are you saying the object-oriented programming is bad or wrong?
A: No of course not! We’re saying always thinking in and always using the object-oriented paradigm in solving problems is bad. Whenever you think in black and white only, that’s wrong.
Even within a single application different problems exist. Multi-paradigm is sometimes the best solution, it al depends on the problem you’re trying to solve.
Whenever you force feed a specific problem to an unfit solution bad things happen.
Q:Are you saying that all frameworks are bad?
W: We’re not trying to judge specific frameworks. We’re dealing with the issue of always using a framework on top of PHP.
Q:If a framework can get me up and running quickly, why is that so bad?
If you have analyzed the situation and long term implications and you then see that “getting up and running quickly” is the only problem you ever have to deal with, then it’s not bad, but then we’re hardly dealing with programming or software development, we’re dealing mostly with point-n-click solutions.
Getting up and running quickly isn’t designing software, it mostly means you haven’t analyzed the problem you’re facing and you haven’t understood the long term implications of your choice.
Q:Are you saying third party packages are bad?
A: No. We’re promoting the use of third party libraries. Code that you easily integrate into your own projects without enforcing any limitations or restrictions what so ever. Those are great!
Coders at work - Reflections on the Craft of Programming
- Based on nearly eighty hours of conversations with fifteen all-time great programmers and computer scientists, the Q&A interviews in Coders at Work provide a multifaceted view into how great programmers learn to program, how they practice their craft, and what they think about the future of programming.
The traits of a proficient programmer
- Competence means having enough experience and knowledge to get stuff done; proficiency involves knowing why you are doing something in a certain way, and how it fits into the big picture. In other words, a proficient practitioner is always a competent practitioner, but the opposite may not be true.
OWASP Secure Coding Guidelines
- This technology agnostic document defines a set of general software security coding practices, in a checklist format, that can be integrated into the software development lifecycle. Implementation of these practices will mitigate most common software vulnerabilities.
- Web application security is an essential component of any successful project, whether open source PHP applications, web services such as straight through processing, or proprietary business web sites. Hosters (rightly) shun insecure code, and users shun insecure services that lead to fraud. The aim of this Development Guide is to allow businesses, developers, designers and solution architects to produce secure web applications. If done from the earliest stages, secure applications cost about the same to develop as insecure applications, but are far more cost effective in the long run.
- This book is for web developers looking to expand their knowledge of creating secure php code, it explains the techniques sometimes used by hackers to gain entry into your website and also explains how to prevent or reduce the chances of those issue occurring to you.
Refactoring Improving the Design of Existing Code
- Refactoring is about improving the design of existing code. It is the process of changing a software system in such a way that it does not alter the external behavior of the code, yet improves its internal structure. With refactoring you can even take a bad design and rework it into a good one. This book offers a thorough discussion of the principles of refactoring, including where to spot opportunities for refactoring, and how to set up the required tests. There is also a catalog of more than 40 proven refactorings with details as to when and why to use the refactoring, step by step instructions for implementing it, and an example illustrating how it works The book is written using Java as its principle language, but the ideas are applicable to any OO language.
- A compendium of practical matters of importance to working programmers.
- The Pragmatic Programmer: From Journeyman to Master examines the core programming process: taking a requirement and producing working, maintainable code that delights its users. It covers topics ranging from personal responsibility and career development to architectural techniques for keeping code flexible, easy to adapt, and reuse.
Understanding programming languages
- The choice of a programming language is one of the most important factors that influence the ultimate quality of a software system. Unfortunately, too many programmers have poor linguistic skills: they are passionately in love with their “native” language, but are not able to analyze language constraints. “Understanding Programming Languages” is written for the purpose of explaining what alternatives are available to the language designer; how language constructs should be used in terms of safety and readability; how language constructs are implemented and which ones can be efficiently complied; and what is the role of language in expressing and enforcing abstractions.
Contribute on GitHub.
- Clone and edit.
- Submit pull request for consideration.
Add sections to the sections directory or edit existing sections.