Fork me on GitHub


A maneira errada

Última atualização: 2018-10-07


No mundo da programação PHP um conjunto de tendências estão sendo massivamente propagadas por algumas pessoas (em seus livros e websites) como “PHP Moderno” enquanto todas as outras abordagens são vistas como atrasadas, estúpidas, ou simplesmente erradas.

Essas pessoas parecem trabalhar incansavelmente no sentido de conseguir que as outras pessoas sigam sua maneira de fazer as coisas.

Esse website foi criado numa tentativa de apresentar uma visão pragmática sobre a programação PHP. Uma visão ditada pela experiência e consequências práticas ao invés de tendências populares, teorias, ou dogmas acadêmicos.

O website PHP - The Wrong Way é um documento livre e continuará sendo atualizado com mais informações assim que estiverem disponíveis.

Sinta-se livre para contribuir.


O perigo do extremismo

Um problema com regras e diretrizes na programação é que elas geralmente só servem a um propósito em um contexto específico. Saindo desse contexto, uma boa regra pode se tornar uma regra horrível. De fato, toda boa regra se torna ruim quando levada ao extremo.

Isso é importante entender porque muitos princípios e regras do desenvolvimento de software desenvolvidas ao longo do tempo e apresentadas por diferentes pessoas frequentemente se tornam mal utilizadas nas mãos de extremistas.

Experience has taught that misuse of general rules and guidelines always results in complication, lack of security, error-prone results, and in some cases complete and utter disaster.

A experiência ensinou que o uso indevido de regras e diretrizes gerais sempre resulta em complicações, falta de segurança, resultados propensos a erros e, em alguns casos, desastre total e completo.

O princípio KISS, que é um acrônimo para “Keep It Simple, Stupid”, é um bom e extremamente sábio princípio que geralmente é visto por pessoas experientes como um conselho muito bom a seguir, mas mesmo este grande princípio torna-se um perigo para um projeto, se levado ao extremo. Existe tal coisa como “muito simples” resultando em falta de funcionalidade necessária.

A maneira errada: Aplicação religiosa de regras e diretrizes. Thumbs down

Sempre use um framework

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 emerged and become popular not because it in any way improves 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 have 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 today’s programmers completely ignore the fundamental principles of sound programming and they spend a large amount of time fantasizing 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 thought 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:

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 in 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 the 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 whilst being as clear and readable 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. Not only did they discover 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. Thumbs down

Sempre use padrões de projeto

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. Worshiping patterns and thinking about, “Oh, I’ll use the X pattern.”

– Brendan Eich in Coders at work - Reflections on the Craft of Programming

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 practically.

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 exists such a thing as an anti-pattern. It is a pattern that may be commonly used but is ineffective and/or counterproductive in practice.

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 in Evil Design Patterns

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: Looking for a pattern to solve a problem. Thumbs down

Sempre use orientação a objetos

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 in Coders at work - Reflections on the Craft of Programming

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 nonsense. 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 in Coders at work - Reflections on the Craft of Programming

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 inflicts 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 its 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 referred to as first- and second-generation languages. Unstructured programming (or non-structured programming) is historically the 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 in 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 as 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 that 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 were not called objects, they were just viewed upon as separate scopes. Later when dependencies were reduced and connections between procedures and variables inside these scopes were 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 were also no longer called “variables”, but were 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 in Ansi Common Lisp

The wrong way: Always use object-oriented programming. Thumbs down

Ter medo do código de outras pessoas

An argument often expressed for the usage of a framework is that people don’t want to deal with codebases that has been written from scratch by other people.

This is however a strange mentality, mainly encountered amongst web developers in the PHP community, it’s one that exudes a lack of professionalism and experience.

Writing software and dealing with other peoples code is normal, it’s part of the daily work of a professional programmer, it’s not something to be afraid of.

A professional programmer doesn’t look at other peoples code and start whining about how he or she is at the complete mercy of the former programmer, who perhaps is no longer associated with the company or project, and if only the former programmer had used framework A or framework B the day would have been saved.

This is not the mentality of a professional programmer. Nobody does this.

Perhaps the low barrier to entry in PHP web development plays a part in this kind of mentality. Regardless, it is a sign of a person being in the wrong line of work.

A great part of programming deals with people having to work with other peoples code. It’s part of the work trying to improve existing codebase and sometimes that involves a complete re-write.

Take note from the great masters of programming, read the book Coders at work - Reflections on the Craft of Programming.

Some of the largest and most successful codebases in world are codebases that has been developed by hundreds of people who have never even met each other, codebases developed without the use of any kind of framework, codebases done entirely in a procedural programming language without the use of anything but the procedural paradigm, and they wouldn’t dream of doing it differently.

The Linux Kernel consist of more than 20 million lines of code all written entirely using procedural programming by more than 14.000 participants without the usage of any kind of framework.

The different BSD flavors and most of the Linux GNU userland has been written entirely using procedural programming without the use of any kind of framework.

The same goes for hundreds of Open Source projects around that world that eventually was abandoned by the original programmer(s) only to be picked up by other skillful programmers. Many of these projects had very little documentation (if any at all), no comments in the codebase, and no guidelines or help to offer at all.

The entire PHP codebase is done in C, a pure procedural programming language, without the use of any kind of framework what so ever.

Whenever you define a class in PHP or whenever you fire up that favorite PHP framework of yours, your running on someones else’s pure procedural work!

Sure, there exists such a thing as horrible code, code that perhaps wasn’t designed from the onset, or code that perhaps has outgrown itself many times but the client didn’t want to deal with a re-write, code that’s so bad you cannot make heads or tail of it any longer, but no kind of framework would have prevented this situation. This is often the natural growth process of a program. Eventually any kind of framework would have been torn to pieces anyway.

And sure there exists horrible spagetti code, but nobody produces horrible spagetti code on purpose. Sometimes this is a result of lack of experience, often times it’s the clients fault because they change the specifications several times in the middle of development, either way in both cases, even if a framework was used, the result would still be spagetti code, and no matter how much of the object-oriented paradigm was used, the result would still be spagetti code.

As programmers we all try to prevent these situations, but this is normal, this is the art of programming, this is part of what it means to be a programmer!

The wrong way: Being afraid of other peoples code. Thumbs down

Following the PHP-FIG standards religiously

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 to 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 religiously. Thumbs down

Negligenciar a segurança

O problema com os programadores é que você nunca sabe dizer o que eles estão fazendo, até que seja tarde demais.

– Seymour Cray on

A programação segura é a prática de escrever programas que são resistentes ao ataque de pessoas maliciosas ou outros programas. A programação segura ajuda a proteger os dados contra roubo ou corrupção. Além disso, um programa inseguro pode fornecer acesso a um invasor para assumir o controle de um servidor ou a identidade de um usuário, resultando em qualquer coisa, de uma negação de serviço para um usuário ao comprometimento de dados sigilosos, perda de serviço ou danos aos sistemas de milhares de usuários

Todo programa de computador é um alvo em potencial para um ataque de segurança. Os atacantes tentarão encontrar vulnerabilidades de segurança em suas aplicações. Eles tentarão então usar essas vulnerabilidades para roubar ou corromper programas e dados e ganhar controle de servidores e redes. Os dados de seus clientes e sua reputação estão em jogo.

A segurança não é algo que pode ser adicionado ao 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.

Uma aplicação insegura pode exigir um redesenho extenso para protegê-la. Você deve identificar a natureza das ameaças ao seu software e incorporar práticas de programação seguras antes e durante o planejamento e desenvolvimento de sua aplicação.

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.

Proteger os recursos críticos do software é mais importante do que nunca, pois o foco dos atacantes se moveu constantemente para a camada de aplicação. Um estudo de 2009, da SANS, descobriu que ataques contra aplicações web representam mais de 60% das tentativas de ataque total observadas na Internet.

O PHP é incomum, pois é uma linguagem de programação e uma estrutura da web ao mesmo tempo. Isso significa que o PHP tem muitos recursos da web incorporados a linguagem, o que torna muito fácil escrever um código inseguro.

Seguro por padrão

A complexidade mata. Isso suga a vida dos desenvolvedores, torna os produtos difíceis de planejar, desenvolver e testar, introduz desafios de segurança e causa frustração de usuários finais e administradores.

Ray Ozzie

Para que as aplicações sejam projetadas e implementadas com requisitos de segurança adequados, práticas de programação segura e um foco em riscos de segurança devem ser integrados nas operações do dia-a-dia, nos pensamentos e nos próprios processos de desenvolvimento.

Geralmente, é muito mais barato construir software seguro do que corrigir problemas de segurança após o pacote de software ter sido concluído, para não mencionar os custos que podem estar associados a uma violação de segurança.

Do jeito errado: Não desenvolvendo software seguro por padrão. Thumbs down


É fácil interpretar de forma errada um documento escrito, então vamos esclarecer algumas coisas.

P: Qual é a intenção desse site e por que essa abordagem de confronto?

R: Para criar uma discussão e reflexão sobre as práticas atuais e visões extremas.

P: Você está dizendo que a programação orientada à objetos é ruim ou errada?

R: Não, claro que não! Nós estamos dizendo que “sempre pensar e sempre usar somente o paradigma de orientação à objetos na resolução de problemas é ruim”. Sempre que você pensa em preto e branco somente, isso é errado.

Mesmo dentro de uma única aplicação existem diferentes problemas. Multi-paradigma é, por vezes, a melhor solução, tudo depende do problema que você está tentando resolver.

Sempre que você força soluções impróprias para um problema específico, coisas ruins acontecem.

P: Você está dizendo que todos os frameworks são ruins?

R: Nós não estamos tentando julgar frameworks específicos. Estamos lidando com a questão de sempre usar um framework para trabalhar com PHP.

P: Se um framework pode me ajudar e executa rápido, por que é tão ruim?

R: Se você analisar a situação e as implicações a longo prazo e, em seguida, ver que “executar rapidamente” é o único problema que você sempre tem que lidar, não é ruim, mas então não estamos trabalhando com programação ou desenvolvimento de software, estamos lidando principalmente com soluções “apontar e clicar”.

Executar rapidamente não é projetar um software, isso significa, principalmente, que você não analisou o problema que você está enfrentando e você não ter entendeu as implicações a longo prazo de sua escolha.

P: Você está dizendo que bibliotecas de terceiros são ruins?

R: Não. Nós estamos promovendo o uso de bibliotecas de terceiros. O código que você pode facilmente integrar em seus próprios projetos sem nunca impor quaisquer limitações ou restrições. Esses são ótimos!

P: Quem é você?

R: Este site é sobre algumas ideias e sobre combater o extremismo na comunidade PHP, não é sobre a fama pessoal ou reconhecimento. Nomear pessoas só vai mudar o foco dos problemas abordados no site para as pessoas que tratam os problemas. Vamos manter o foco nas idéias.

P: Qual é a sua experiência no desenvolvimento de software?

R: As ideias, pensamentos e conclusões expressas neste site não necessitam de muita experiência para serem alcançadas, se você apenas manter o foco sobre o tema principal, que é fazer sempre uma coisa em particular porque outras pessoas dizem isso.

Leitura recomendada

PHP The Wrong Way on Hacker News

Why bad scientific code beats code following “best practices”

How to program without OOP

Coders at work - Reflections on the Craft of Programming

The traits of a proficient programmer

OWASP Secure Coding Guidelines

Security by Design Principles

Survive The Deep End: PHP Security

Refactoring Improving the Design of Existing Code

The Practice of Programming

The pragmatic programmer

Understanding programming languages

Como contribuir

Contribua no GitHub.

Adicione seções no diretório sections/LANGUAGE ou edite uma seção existente.