php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #49686 SPL as a shared ext: run-time check for SPL instead of compile-time
Submitted: 2009-09-27 10:26 UTC Modified: 2009-09-28 03:22 UTC
Votes:4
Avg. Score:3.0 ± 0.0
Reproduced:4 of 4 (100.0%)
Same Version:4 (100.0%)
Same OS:4 (100.0%)
From: galaxy4public+php at gmail dot com Assigned:
Status: Wont fix Package: Feature/Change Request
PHP Version: 5.3.0 OS: Linux
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: galaxy4public+php at gmail dot com
New email:
PHP Version: OS:

 

 [2009-09-27 10:26 UTC] galaxy4public+php at gmail dot com
Description:
------------
The attached patch introduces a run-time check for the SPL extension instead of the compile-time one.  This allows to build SPL as a shared extension (the corresponding changes to config.m4 are included in the patch as well).

This work was sponsored by the WebEnabled (http://webenabled.com) project.

Since there is no way to attach patches to bug reports I'm including it below:
===
--- php-5.2.5.orig/ext/spl/config.m4    2006-12-04 18:01:53 +0000
+++ php-5.2.5/ext/spl/config.m4 2008-04-07 05:53:55 +0000
@@ -26,7 +26,7 @@
   CPPFLAGS=$old_CPPFLAGS
   AC_DEFINE_UNQUOTED(HAVE_PACKED_OBJECT_VALUE, $ac_result, [Whether struct _zend_object_value is packed])
   AC_DEFINE(HAVE_SPL, 1, [Whether you want SPL (Standard PHP Library) support])
-  PHP_NEW_EXTENSION(spl, php_spl.c spl_functions.c spl_engine.c spl_iterators.c spl_array.c spl_directory.c spl_sxe.c spl_exceptions.c spl_observer.c, no)
+  PHP_NEW_EXTENSION(spl, [php_spl.c spl_functions.c spl_engine.c spl_iterators.c spl_array.c spl_directory.c spl_sxe.c spl_exceptions.c spl_observer.c], $ext_shared)
   PHP_INSTALL_HEADERS([ext/spl], [php_spl.h spl_array.h spl_directory.h spl_engine.h spl_exceptions.h spl_functions.h spl_iterators.h spl_observer.h spl_sxe.h])
   PHP_ADD_EXTENSION_DEP(spl, pcre, true)
 fi
--- php-5.2.11.orig/ext/standard/array.c        2009-08-14 06:18:47 +0000
+++ php-5.2.11/ext/standard/array.c     2009-09-27 08:46:42 +0000
@@ -324,20 +324,22 @@ PHP_FUNCTION(count)
                        RETURN_LONG (php_count_recursive (array, mode TSRMLS_CC));
                        break;
                case IS_OBJECT: {
-#ifdef HAVE_SPL
-                       /* it the object implements Countable we call its count() method */
-                       zval *retval;
-
-                       if (Z_OBJ_HT_P(array)->get_class_entry && instanceof_function(Z_OBJCE_P(array), spl_ce_Countable TSRMLS_CC)) {
-                               zend_call_method_with_0_params(&array, NULL, NULL, "count", &retval);
-                               if (retval) {
-                                       convert_to_long_ex(&retval);
-                                       RETVAL_LONG(Z_LVAL_P(retval));
-                                       zval_ptr_dtor(&retval);
+                       zend_class_entry **pce;
+                       /* check whether the SPL extension available or not */
+                       if (zend_hash_find(EG(class_table), "countable", sizeof("Countable"), (void **) &pce) == SUCCESS) {
+                               /* if the object implements Countable we call its count() method */
+                               zval *retval;
+                               if (Z_OBJ_HT_P(array)->get_class_entry && instanceof_function(Z_OBJCE_P(array), *pce TSRMLS_CC)) {
+                                       zend_call_method_with_0_params(&array, NULL, NULL, "count", &retval);
+                                       if (retval) {
+                                               convert_to_long_ex(&retval);
+                                               RETVAL_LONG(Z_LVAL_P(retval));
+                                               zval_ptr_dtor(&retval);
+                                       }
+                                       return;
                                }
-                               return;
                        }
-#endif
+
                        /* if not we return the number of properties (not taking visibility into account) */
                        if (Z_OBJ_HT_P(array)->count_elements) {
                                RETVAL_LONG(1);
===


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-09-27 10:34 UTC] galaxy4public+php at gmail dot com
Since the patch was broken by line-wrapping I've uploaded it here:
ftp://ftp.ru.openwall.com/pvt/galaxy/php-spl-shared/php-5.2.11-gm-spl-shared.diff
 [2009-09-27 10:37 UTC] galaxy4public+php at gmail dot com
Ouch, this line-wrapping feature really hurts! :(  In the comment above the link should be manually concatenated to get a correct URL.
 [2009-09-27 11:23 UTC] galaxy4public+php at gmail dot com
Well, I made the directory world-readable:

ftp://ftp.ru.openwall.com/pvt/galaxy/php-spl-shared/

I'll place any updates to the patch there (if there are any).
 [2009-09-27 19:35 UTC] scottmac@php.net
SPL is force enabled with PHP 5.3+ as static, so this patch really only applies to 5.2 and I'm not sure if we're still open for new features.
 [2009-09-27 19:57 UTC] pajoye@php.net
I think we can safely reject the patch. Unless someone has a strong argument to allow 5.2.12 to do not be forward compatible in some install (as in not having spl enabled :).
 [2009-09-28 03:05 UTC] galaxy4public+php at gmail dot com
Actually the patch changes 2 lines in ext/array.c and makes it possible to build SPL as a shared extension (all other code is already in place).  In 5.3.0 somebody removed a couple of configuration lines from ext/spl/config.m4 and made it impossible to configure SPL with the configure script.  I believe that this was done due to the fact that calls to SPL are all hardcoded dependencies.

Frankly, I don't understand why hardcode things when the mechanism for dynamic loading is already here.

Instead of unconditionally rely on things like:
===
if (Z_OBJ_HT_P(array)->get_class_entry && instanceof_function(Z_OBJCE_P(array), spl_ce_Countable TSRMLS_CC)) {
===

why don't you use something like:
===
if (zend_hash_find(EG(class_table), "countable", sizeof("Countable"), (void **) &pce) == SUCCESS) {
if (Z_OBJ_HT_P(array)->get_class_entry && instanceof_function(Z_OBJCE_P(array), *pce TSRMLS_CC)) {
===

Then, you can:

a) drop '#ifdef HAVE_SPL' around this blocks, since they will no longer strictly depend on SPL;
b) it will be possible to build/load SPL dynamically (with no or little effort)

Otherwise, what's the point of having "extensions" if they aren't extensions but an integral part of the interpreter and can't be loaded dynamically?

What really missing in PHP is a good extension dependency mechanism (and, perhaps, auto extension loading), IMHO.
 [2009-09-28 03:22 UTC] galaxy4public+php at gmail dot com
What really concerns me in regard to SPL as a static extension is that many other extensions depends on it.  For instance, with SPL statically linked into PHP it's not possible to build the PCRE extension as shared, and there more extensions which could have been dynamically built if SPL was allowed to be "shared".

Consider the following scenario (we are currently running on our servers):  we have a shared hosting environment with hundreds of virtual hosts and each additional unneeded extension consumes server's memory, hence we provide a very basic PHP interpreter with no extensions loaded.  Then, users can load needed extensions vi their local php.ini or using dl().

That's why I'm trying to convince you that making "extensions" to be really extensions (i.e. dynamically loaded parts) is quite important.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 26 20:01:29 2024 UTC