PHP框架全部顯得多餘的4種原因

字號+ 編輯: 种花家 修訂: 种花家 來源: PHP Classes 2023-09-11 我要說兩句(5)

PHP創始人 Rasmous Lerdorf 談到php框架, 語出驚人——他竟然說所有php框架都是垃圾, 既然如此, 把會議相關記錄展示一下, 供大夥訢賞。

PHP Frameworks Day

PHP Frameworks day is an event that took place in Kiev, Ukraine, last October. It is an event with talks about different frameworks.

I only became aware of it now thanks to PHP Quick Fix stream of news that Chris Cornutt (AKA enygma) of PHPDeveloper.org fame puts together. Thanks Chris.

Why All PHP Frameworks Suck

Rasmus Lerdorf, PHP創始人, 應邀在PHP框架日會議上發表演講。他主要講說了最新的PHP研發,但對我來說最爲有趣的一塊是問答部分。

除此之外,有人問Rasmus他怎麽看PHP框架的。這是一個直接問及他觀點的問題, Rasmus也給出了直接的答案 (視頻 31分 47秒): "它們 (指PHP框架) 都是垃圾!"

可能一個演講嘉賓去PHP框架大會上講說PHP框架都是垃圾, 會讓人詫異, 但聽衆卻對這種答案卻很滿意。不管怎樣吧,Rasmus還是細講了他所要表達的具體意思。

1. Frameworks Execute The Same Code Repeatedly Without Need

Rasmus認爲所有框架總體來說並沒有滿足每個人的優化需求。

A more specific complaint was that the solutions that frameworks offer lead to executing needless PHP code repeatedly in every HTTP request. The example that Rasmus gave is that in every request frameworks check the database type the application is using to load the respective database access class. Since the database type does not change after an application is deployed, he sees this as a waste.

While I agree with Rasmus, I think this example is not very compelling because checking the configuration to decide which database access class to load takes a very small fraction of time, especially when compared for instance with executing database queries, which usually take many milliseconds and sometimes take a few seconds to run.

A better example of this problem is when frameworks need to read configuration files to define load the actual configuration values.

Often frameworks read configuration from INI files. PHP has built-in functions to load and parse INI files. Despite you can do it all with a single function, reading a INI file and parse it takes some time that is usually way more than checking the parsed configuration values.

If your framework reads and parses configuration values from files in other formats that PHP does not have built-in support, like for instance YAML or XML, things get worse because the frameworks have to do the parsing in pure PHP code. That is much slower than the C code of the PHP engine that parses INI files.

A better alternative is to have configuration values defined in PHP script files. Just put the configuration values in PHP scripts that assign the values to variables.

When you use a PHP caching extension, PHP scripts are only compiled once. On a second run, PHP scripts compiled into opcodes are loaded from RAM. That is much faster than loading configuration from files.

2. Frameworks Require Too Many Interdependent Classes

另外Rasmus提到有時候你只需要框架的一部分功能而已,不過自從框架裡的類有了依賴關係之後,盡管你只是辦個簡單的事, 仍需要加載這些沒用的依賴。

While this is true to a certain degree, I have seen efforts from certain framework developers to reduce the dependencies between distinct components. Still there are often dependencies between many frameworks classes that sometimes do not aggregate anything to an application with specific needs.

To address this problem some developers need to change the frameworks to strip the needless parts that add overhead. This causes a maintenance nightmare because they need to do that every time they want to upgrade to a newer version of a framework they started to adapt for their needs.

Rasmus suggests using frameworks optimized for specific purposes to avoid this problem. He recommends using for instance Wordpress or Drupal if you just want to publish a blog.

Alternatively Rasmus suggests that frameworks provide a means to let the developers push to production just a small subset of the components that are needed in each application.

This solution is too general. Rasmus did not get to the way certain frameworks implement things and so he did not comment on why certain frameworks need so many components.

For instance many frameworks rely on runtime ORMs (Object Relational Mapping). These are components that let developers define how to query databases treating information as objects, rather than tables of records.

Object orientation is fine for abstracting problems and encapsulating solutions into classes of objects, but the way certain ORMs work adds too much needless overhead.

The developer has to write code to dynamically specify the class variables (tables fields), condition clauses, object relationtionships (table joins), etc... to compose the actual query at runtime. This adds a lot of overhead because the queries that are executed are the same on every request, apart from some parameter values that may vary.

There is a better solution that avoids this overhead. Instead of dynamically composing queries at runtime, just have a separate tool that generates PHP code for the ORM classes. The generated classes already have the compiled SQL queries to execute without further overhead at runtime.

I have been using this approach since 2002 when I developed a ORM tool named Metastorage. It does exactly what I described above. I define in project file the objects, variables, relationships and functions that I need to apply on objects.

Metastorage processes my objects definitions and generates ORM classes that execute the necessary queries at runtime just by calling the classes functions. No query building is done at runtime.

3. 不必要的複雜解決方案 Needlessly Complicated Solutions

One thing that Rasmus did not mention directly is about the complicated solutions that frameworks tend to push.

That is the case for instance of application version migrations. Some frameworks have copied the concept of migrations from Ruby On Rails. This means that you have to write code to change your database schema between different application versions.

This is another thing that Metastorage addresses in a more efficient and less painful way for developers. Metastorage generates database table schema definitions in a separate file from my object definitions. It generates an installation class that installs the database tables on the first time.

If I change the object definitions, the installation class can also upgrade the schema with the newer definitions without destroying any data already inserted in the database tables.

This certainly makes development much faster and application upgrades less error prone because the tool always generates correct code to upgrade the database schema. When you write migrations code by hand, you may make mistakes that make you spend more time and effort to fix.

4. Duplicating the Web Server Functionality

另一點Rasmus沒直接提到的是,  框架有時重複理順一堆web服務中間件早就干過的事。

For instance, routing is the processes of assigning some code (a controller) to handle requests with different URL patterns. Many frameworks push applications to use the front controller pattern. The front controller analyzes the request URL and load a specific controller to actually handle the request.

The matter here is that the Web server already does this. It can match the request URL against configuration (for instance of mod_rewrite or similar) and execute the appropriate PHP script.

When you make PHP handle the routing process, you are adding needless overhead to perform a task that is the same for every request with the same URL pattern. This falls into Rasmus complaint of frameworks that execute the same code repeatedly to the reach the same outcome.

This seems to be yet another bad influence that PHP frameworks got from Ruby On Rails and Java. With those languages the Web server forwards the request to an application server.

PHP does not need to work this way because it always runs integrated with the Web server, so there is no point duplicating the Web server functionality in a way that is slower and adds more overhead.

Other Questions

在本次會議上, Rasmus也回答了我認爲值得評鋻的其他有趣問題, 。

Dropping APC in Favour of Zend Opcode Cache

This is a topic that we have discussed several times in the Lately in PHP podcast. Rasmus explained that PHP needed to adopt one opcode cache that would follow the latest PHP developments on every new release.

There are several opcode caches. Rasmus decided to give up on APC in favour of Zend's solution because it is more mature and faster. That required Zend to make their solution Open Source.

Curiously the maintainer of the now official PHP opcode cache is Dmitry Stogov. He was the original developer of the Turck MMCache that Zend hired to work on their on cache extension some years ago.

All is well when it ends well. Too bad that PHP took all this time to have an official caching extension. The lack of an official extension made PHP look bad in many benchmarks that in the past favored other languages.

Compiling PHP into Binary Code

有人問PHP能不能有一套編譯成某種二進制形式的庫文档的模式來保護代碼。

Rasmus陳述說PHP不會把那種東西内置進去,他证明事實上Zend(和其他)公司提供了相應的解決方案不過也很好破解。所以他寧願不參與其中。

While this is true, Rasmus is just considering solutions that merely compile PHP into opcodes and encrypt the result. This is a solution that is really not so hard to break by hackers.

However there are better solutions that consist in compiling the result code into native assembly machine code. While it is always possible to decompile machine code, it is much hard to reverse engineer it to PHP code that is useful enough to be understood by people that wants to steal work or change it in some useful way.

One concern that many developers that look for copy protection solutions of PHP code, is that somebody with access to the servers where the code is installed, changes the code easily.

I have seen many times developers that work for customers and those customers just go there and change their code without the knowledge of the developers. This creates maintenance headaches. Sometimes customers complain about code that is not working well because in reality they changed the code. So a solution to make it harder to view or change installed code would help.

For those cases, nowadays developers can minimize that problem by creating PHAR archives. These are binary archives that contain one or more PHP scripts. While PHAR archives are not really a copy protection solution, at least they would make it harder for customers that want to poke on the developers code.

$ Dollar Sign in PHP variables

When asked about why variables start with the $ sign, he explained that was meant to be able to insert variables inside literal string values, so a mark would need to be used to distinguish what is a variable from the rest of the string.

Since he wanted the variables to look the same inside and outside a string, he has chosen the $ sign to start variables, inspired in the solution that Perl also adopted.

Node.js and Non-Blocking I/O

當問到PHP可否支持非IO阻塞編程, Rasmus解釋到, 大夥可以使用 libevent 擴展。不過那類編程 Rasmus更傾向於使用 Go 語言。

無論如何,異步編程 (非IO阻塞)也就是Node.js有一種遺憾,寫起來感覺很不舒服, 因爲他要解決每個閙心的回調函數。

閙心的回調函數編程導致一些坑問題,例如無法在回調函數内break while循環。 This is a topic that we discussed several times in the Lately in JavaScript podcast

Unicode and JIT on PHP 7

When asked about the plans for future PHP versions, Rasmus commented that he learned from the PHP 6 Unicode support failure that it was a goal that was too ambitious. So he expects that PHP evolves in smaller hops.

Two goals he thinks are too ambitious but will eventually be implemented maybe in PHP 7 are the native support to Unicode based on a simpler approach than ICU, and a JIT compilation engine probably based on Google V8 or Facebook HHVM.

Conclusion

Rasmus interview was very interesting because it makes us reflect on the way we are doing things in PHP that may be less than ideal, especially when you use general purpose frameworks.

Whether you agree or disagree with the points of view, post a comment here to tell what you think about these topics.

閲完此文,您的感想如何?
  • 有用

    190

  • 沒用

    6

  • 開心

    33

  • 憤怒

    19

  • 可憐

    25

1.如文章侵犯了您的版權,請發郵件通知本站,該文章將在24小時内刪除;
2.本站標注原創的文章,轉發時煩請注明來源;
3.交流群: 2702237 13835667

相關課文
  • mac開發接入微信公衆號接口返回報錯 cURL error 56: SSLRead() return error -9806

  • pecl安裝程序時報錯Array and string offset access syntax with curly braces is no longer supported

  • PHP的換行符是什麽

  • 由於商家傳入的H5交易參數有誤,該筆交易暫時無法完成,請聯繫商家解決

我要說說
網上賓友點評
1 樓 IP 101.19.***.12 的嘉賓 说道 : 很久前
呵呵

2 樓 IP 101.19.***.12 的嘉賓 说道 : 很久前
不错

3 樓 IP 106.2.***.86 的嘉賓 说道 : 很久前
希望尽早出JIT

4 樓 IP 106.2.***.86 的嘉賓 说道 : 很久前
框架分多钟

5 樓 IP 111.192.***.181 的嘉賓 说道 : 很久前
现在的php框架,除了yaf全都是辣鸡!