php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #53957 Unloading Extentions OR Overriding Native Functions OR Importing Functions
Submitted: 2011-02-08 11:27 UTC Modified: 2011-02-08 11:34 UTC
From: landeholm at gmail dot com Assigned:
Status: Wont fix Package: Scripting Engine problem
PHP Version: 5.3.5 OS: Irrelevant
Private report: No CVE-ID:
Have you experienced this issue?
Rate the importance of this bug to you:

 [2011-02-08 11:27 UTC] landeholm at gmail dot com
Description:
------------
I'm building a framework which has a custom gettext implementation since the gettext extension of PHP is poorly designed for my needs and it's not installed in all environments so relying on it reduces compatibility. The problem however is that it's installed in some environments and since it claims the global "_" function which is pretty much a gettext standard alias (and other gettext functions), it's preventing me from implementing the gettext standard. There are no possible way for me to solve this problem nicely today because PHP does not have the ability to either:

A. Override/undeclare/rename native functions. (Okay, I can do it via APD but that makes extension dependability even WORSE.)
B. Unloading extensions at runtime. (Most preferable... I don't want it at all)
C. Importing functions. (My framework uses namespaces. The fact that functions cannot be imported by the "use" keyword really spoils this feature. Otherwise it could actually have fix this problem.)

Note that this problem assumes a context where you can't control the environment in which you install your application in. This is a very real scenario for a lot of people including me. This is a practical problem, not a theoretical one.

Also note that declaring the "_" function in a namespace would be pointless:
1. it would no longer be compatible with the gettext standard
2. it would require refactoring of all existing string wrapped code
3. it would no longer be compatible with existing string wrapped code
4. a longer name like \foo\translate_lib\_() defeats the point of having a short function name

Another workaround is to declare a _ forwarding function in every possible namespace, but that solution is dumb and ugly.

As a temporary workaround I might declare something like t\s() but I don't like that solution and it doesn't solve 1, 2 and 3 above.

Test script:
---------------
/** EITHER A: */
undeclare_function("_");

/** OR B: */
unload_extension("gettext");

/** OR C: */
namespace foo;
use foo\translate_lib;

/** Test: */

// My gettext implementation.
function _($msgid) {
   return translate($msgid);
}

echo _("hello");

Expected result:
----------------
bonjour

Actual result:
--------------
Fatal error: Cannot redeclare _()

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-02-08 11:34 UTC] rasmus@php.net
-Status: Open +Status: Wont fix
 [2011-02-08 11:34 UTC] rasmus@php.net
extension unloading on a per-request basis simply isn't feasible from a 
performance point of view.  And you obviously can't unload and leave it unloaded 
for the next request because that next request may be for a page that expects the 
extension to be there.
 [2011-02-08 11:46 UTC] landeholm at gmail dot com
Thanks for your reply. Yes, I understand that it's unrealistic to expect a feature that allows dynamic extension unloading. But how about allowing function importing with the "use" statement? Regards~
 [2011-02-08 12:41 UTC] landeholm at gmail dot com
Some workaround notes: I'm currently solving this by the workaround previously described as "dumb and ugly" by a little twist. I'm dynamically adding forwarders for the functions that needs to be imported by using a routine that goes trough all namespace locations and creates a forwarder function by evaluating generated PHP code that looks something like:

namespace source_ns; function source_fn() { return call_user_func_array('target_ns\target_fn', get_func_args()) } ...

Eval is slow though... If I could populate the symbol table directly instead doing it by eval() this would be acceptable. What I want is dynamic function declaration like declare_function($name, function() { ... });

The eval method however works temporary since the low amount of function imports only makes this routine use a couple of ms.
 [2011-03-14 11:30 UTC] marcus at synchromedia dot co dot uk
I have a weird problem where extensions are apparently unloading dynamically when 
I don't want them to!
At the beginning of a script I can call get_loaded_extensions and see 50+ 
extensions. Later on (in the same script) a few of them disappear, in particular 
apc and memcache, so attempts to instantiate memcache clients or call apc_store 
result in undefined class/function errors.
I didn't even think this was possible; I've no idea what mechanism is at work 
here, and I don't know precisely when these extensions disappear, but they do. I 
don't know if this is a bug/feature, or something you can use to fix the orginal 
question!
 [2011-03-14 13:48 UTC] marcus at synchromedia dot co dot uk
Ignore last comment. Turned out to be due to inadvertent switching between two 
local interpreters.
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sun Apr 20 08:02:33 2014 UTC