I have nearly twenty years of programming experience and have developed in various programming languages. In many of the jobs I've had and in the job I'm doing now, I'm very excited to have PHP as my core programming language. From the first time I started working with PHP, I heard all kinds of complaints about PHP, but at the same time I also saw the power of PHP.
PHP is at least an interesting programming language. The language and the programs built with it generally fall into two design philosophies. Here, I'm not talking about software development life cycles like Waterfall or Agile, but the basic idea of what software should be. These ideas are called "The Right Way" and "Worse is better."
PHP is another rather strange programming language. When people complain that the language "sucks," they're not wrong. There are indeed a lot of bad things about this language. Back in the day, the language had more terrible problems. The blog post that mocks PHP, "PHP: a fractal of bad design," does have a few valid points, even if they were out of date when it was published nine years ago.
At the same time, however, developers can use PHP to create structurally "correct" software and import philosophies from other languages that are considered good practices. Frameworks like Laminas and Symfony use the best practices of object-oriented programming, allowing developers to write structurally correct code using these frameworks.
How does PHP do this? This is because PHP is the worst programming language.
Design Software
In 1991, Richard P. Gabriel published an article "Lisp: Good News, Bad News, and How to Win Big 》(Lisp: Good News, Bad News, How to Win Big). The argument of this article is that a "worse is better" philosophy would be the better choice when it comes to software design and longevity. He came to this conclusion because he recognized the emergence of two different schools of programming, which he named the "MIT/Standford Style," or the "Correct way," and "New Jersey Style," or "worse is better."
The two philosophies have similar goals but differ in key areas. Both styles focus on four key areas of philosophical philosophy: Simplicity, Correctness, Consistency, and Completeness.
MIT style is described like this:
Simplicity: The design must be simple, regardless of its implementation or interface, it must be simple. In comparison, it is more important to keep the interface simple.
Correctness: The design must be correct in all observable aspects. Don't presume to make an incorrect design.
Consistency: The design must not be inconsistent. To ensure consistency, you can slightly sacrifice simplicity and completeness. Consistency and correctness are equally important.
Completeness: The design must cover as many important situations as possible. All expected situations must be covered. Completeness should be prioritized over simplicity.
As for New Jersey style, Gabriel says it defines its goals as:
Simplicity: The design must be simple, regardless of its implementation Both interfaces must be simple. In comparison, it is more important to keep the implementation simple. Simplicity is the most important, and no other feature is as important as keeping it simple.
Correctness: The design must be correct in all observable aspects. But correctness can be slightly sacrificed for simplicity.
Consistency: The design must not be too inconsistent. In some cases, consistency can be sacrificed for simplicity. If introducing an unusual situation into the design would make the implementation complex or inconsistent, then don't consider it.
Completeness: The design must cover as many important situations as possible. All expected situations must be covered. Integrity can give way to any other characteristic. In fact, completeness must be sacrificed once implementation simplicity is threatened. If you want to keep things simple, you can sacrifice consistency for completeness; especially interface consistency.
The key to this debate is to use LISP and C as examples of why "worse is better". For LISP programmer Gabriel, LISP is a better language than C, as fast as C, and Common LISP has taken many years to design, develop, and standardize. The specification that defines the language draws on the best of all the different LISPs, and modern development environments are the best for LISP developers.
LISP is the right way
LISP represents the "right way" of software development. LISP is easy to interact with, and you can interact with it in a variety of ways. Want to call LISP from Fortran? You can call LISP from Fortran and pass data in, and vice versa. You can happily use all of LISP's modern "luxury" features when working with legacy code.
LISP has a consistent design thanks to its specification. If you look at a modern language like Python, specifications go a long way in providing multiple backends and compilers, and they all interpret or compile code in the same way. The tools were top-notch, and LISP in 1991 had all the comforts we still enjoy today, like step debugging, data inspection, and fancy editors.
As a language, LISP is complete. It features an advanced object-oriented programming layer, multiple inheritance, first-class objects, and functions and types. LISP seems to be the programming language developers have in mind.
In 1991, a programming language like LISP was probably in the best shape it had ever been. This technical correctness has not been proven by actual use. LISP developers are declining. LISP's external reputation has been hampered by years of negative press and mispositioning. People no longer think of it as a way to deliver software to end users.
In terms of development, LISP often represents many of the same ideals as Big Design Up Front (BDUF). If you have ever used a design method like the Waterfall Model, you will have discovered some problems. The “right way” places a strong emphasis on consistency, correctness, and making sure every conceivable issue is taken into account.
LISP itself is not a single language, but a family of languages. Although Common LISP is designed to be a standard, the implementation of LISP itself exists based on the various tasks that need to be done. An article on the Lockless Inc website points to this “fragmentation” as one of the determining factors in LISP’s eventual failure. Although LISP adheres to the "right way" of software design, this fragmentation results in code maintenance and portability being compromised.
C and Unix are the wrong way
At the same time, due to the emergence of Unix, C language gradually became the preferred method of software development. C was designed for Unix, and Unix was designed in C. Its developers had a different design stance from MIT's LISP and its authors.
In 1972, C was designed to be a simple language. By 1991, it had changed a bit, but the basic principles of the C language had not. Some features were added to meet the needs of developers and Unix. Because the language is simple, writing compilers and programs is easy. While the language doesn't prevent you from doing complex programming, C is estimated to have only 50-80% of the features a programmer needs compared to LISP.
However, the C language is highly portable. It can also run on lower power hardware than is commonly used in LISP software and environments. This factor makes it possible to compile and run the software on a wider range of machines. C and Unix are easy to use, and Gabriel thinks Unix and C will go viral.
The C language evolved while Dennis Ritchie was designing and building Unix. Because Bell Labs was not allowed to officially enter the computer field, Unix could also be easily distributed to a variety of users. These users help patch Unix to suit their own needs. Dennis Ritchie was able to put these patches together as needed without having to think about those needs in advance.
Unlike LISP, C is still widely used today. Although high-level interpreted languages such as PHP, JavaScript, and Python are the first choice of many developers, many of these high-level languages are developed in C. Even as competitors like Rust start to emerge, the ability to run on small, low-power devices remains a strength of C.
PHP is the worst
Therefore, "worse is better" software will be accepted first, and second It will make users expect less, and third, the software will be continually improved until it's close to the "right way."
- Richard Gabrie
A few years after this revelation, Rasmus Lerdorf began working on a personal homepage/form interpreter that we now know as PHP. PHP/FI was born out of Lerdorf's need to maintain his home page and interact with forms and databases. PHP/FI was not even designed as an actual programming language, but as a layer of scripts and functions on top of the C language.
PHP is very simple
The design must be simple, whether it is its implementation or interface.
PHP uses the C language at the bottom. We have said before that this part is the "worst". However, this also brings some advantages, most importantly, a simpler underlying language that makes it easier to extend. While Hack/HHVM takes a more C approach, PHP itself is still a C language.
It only takes a few hours to learn the internal structure of this language. Elizabeth Smith gave a great talk on PHP extensions that covered a lot about the inner workings of PHP. The language itself draws on other C-style languages, which is not only easy to read, but also convertible to other C-style languages.
Most of PHP's interfaces, or standard libraries, are very simple, because most of the core functions are just wrappers of various C language libraries and then exposed almost unchanged. Although doing so results in some inconsistencies in the interface, it provides a familiar environment for developers coming from C or C++.
The PHP language is heavily focused on web development. It's often very simple to extract concepts from HTTP and find similar concepts in the language. Want to know the header information of a request? get_headers() will satisfy you. Obtaining request information is as simple as reading the $_GET and $_POST global variables.
PHP maintains a simple developer interface and keeps its internal structure as simple as possible.
PHP is (almost) right
The design must be correct in all observable aspects. But correctness can be slightly sacrificed for simplicity.
Here, PHP tends to choose "simple" over correct. Before the advent of HHVM, the language's appearance and features had not been standardized. The Zend interpreter itself is the specification, and the way the language behaves is always "correct" (excluding actual errors). If you want to replace the PHP engine with something else, you must implement all the features of the existing engine.
LAX function parameter and return types for many core functions make the system's work easier. Functions like strpos() can return integers or Boolean values, which is slightly easier to handle than methods strictly designed to return integers or throw exceptions.
Looking at the development of the PHP language, almost all new features are based on what developers need, rather than the serious idea of "it must be fixed because it is wrong". Focusing more on those strict type and exception errors is a more correct way of doing things. However, there are also things like short arrow functions, properties, and enumerations that developers want to use to simplify their code.
PHP does not require consistency
The design must not be too inconsistent. In some cases, consistency can be sacrificed for the sake of simplicity.
I'm not even going to pretend that PHP is consistent, but it's consistent enough. People may complain about needle/haystack argument order when it comes to array vs. string functions. However, in general, array functions are consistent, and string functions are also consistent. It's much simpler to be consistent with the underlying C library than it is within the language.
PHP is consistent enough in other aspects as well. As I mentioned with strpos(), PHP tends to return FALSE fairly consistently for functions that encounter an error. This is not necessarily correct, but it is consistent. Underscored and non-underscore function names generally match their underlying libraries.
The PHP language sacrifices consistency for simplicity, but even without this specification, it still strives to be consistent where it makes sense.
PHP's completeness meets the requirements
The design must cover as many important situations as possible.
PHP is complete whenever you need it for the most demanding design task: writing web applications. PHP was never designed to be a language that could be applied to all problems in the programming world. Still, its simplicity makes it usable beyond the Web. The original purpose of PHP was to provide the most basic functions for web programming, and this trend continues today.
Modifications to the core language are often driven by developer needs. The entire community proposes modifications, and then the community votes to decide whether the new feature is rejected, changed, or accepted. Many innovations in the language stemmed from the need to get things done quickly. Even when we absorb features from other languages, it's because it makes our development easier, rarely because other languages do it "more correctly."
Today, you can develop web applications using PHP. Five years from now, you can still develop web applications in PHP, just with some new features. However, the integrity of the language itself is adequate for today's needs. We can always modify the language or add new features to it if needed in the future.
Is worse better?
Gabriel admits that the "worse is better" philosophy refers to designs that look bad and maybe shouldn't be considered a better option. The only problem is that when he looks at both philosophies, "worse is better" is still ultimately the more flexible option, compared to the MIT/"right way" design philosophy, "with better survival characteristics”. If we look at PHP, we can confirm the idea that "worse is better".
Over the years, Gabriel admits he has wavered between which way is better. The PHP community has been debating whether we should do things right or keep doing things simply. We have frameworks like Laminas, which build libraries in a classic computer science way, and then we have frameworks like Laravel, which focus on developer experience and speed. PHP itself is both.
Next time you hear someone criticizing PHP, just let them go. The language is really bad. But in many ways, PHP's longevity and widespread use are testament to the fact that doing things the "right way" isn't always better than the "worst" way. When someone complains about the framework you're using, understand that it doesn't matter in the long run. Choose a design philosophy that you think works for you, and embrace the fact that worse might actually be better.
Original link: https://www.phparch.com/2021/09/education-station-php-is-the-worst/
Original author: Chris Tankersley
About the Author:
Chris Tankersley wears many hats: husband, father, author, speaker, podcast host, and PHP developer. Chris has used many different frameworks and languages during his 12-year programming career, but he spends most of his day working with PHP and Python. He is the author of Docker for Developers and works with companies and developers to integrate containers into their workflows.
Recommended learning: "PHP Video Tutorial"