How to redefine a function in php? - php

Now i'm stuck with file_exists() function. My project is built from repositories, one is symlinked as a DocRoot, others are available to php interpreter via include_path. But the default file_exists() cannot look at the files are placed somewhere under include_path, so i need or somehow redefine this func with a wrapper or to write my own, include it in other modules and replace all matches of this func in the directory tree. It's possible, but is not good and is not clear for developers.
I've already seen pecl-apd (2008) and pecl-runkit (2007), but there are no more such pecls among the others in my gentoo repository or the overlays. So, how to redefine a function in a modern way?
== upd ===
Ok. Let's go deeper.
Assume we have /home/me/repos/ directory, where our git modules are placed and a virtual host /var/srv/domain.com, where it all is assembled
repos_
\_site_root_
\_.git
\_file1
\_module1_
\_.git
\_we_need_this_file_too
\_module2_
\_.git
domain.com_
\_htdocs –> ~/repos/site_root
\_tmp
so we need to somehow include folders with modules 1 and 2 into the project. Then adding path to ~/repos to php include_path via vhost config
php_admin_value include_path ".:/home/me/repos"
Now php can
include ('module1/we_need_this_file_too');
from my repos directory. but when it tries to check the file before including with file_exists(), it fails, because those directories are still closed for file_exists(). This is the problem.
Now i've found a workaround with absolute paths, anyway i'd have to create a personal config in my project. I also though about to chdir() into /home/me/repos/ when it needs to (and describing <Directory> section in vhost), but it was bad idea.

From the PHP manual
PHP does not support function overloading, nor is it possible to undefine or redefine previously-declared functions.
Well, you may, as you already mentioned, if you install the runkit extension and use runkit_function_redefine or if you install APD and use override_function.

I working on library for function redefining in php5.3
Source: https://github.com/Bubujka/bu.defun
Exampls: http://defun.bubujka.org/doc.html
Simple redefining:
<?php
def('name', function(){
echo "Waserd";
});
name();
echo "\n";
def('name', function(){
echo "Bubujka";
});
name();
---
Waserd
Bubujka

Related

No include_paths are working for Zend

I'm running out of ideas here. Physically, my Zend install (XAMPP on Windows) is located at D:\xampp\htdocs\newsite\zend\library.
So far, I've managed to fail with all of the following include paths, as reported in zend.php (located at D:\xampp\htdocs\newsite and accessed from 127.0.0.1/newsite/zend.php.
.;D:\xampp\php\PEAR
.;D:\xampp\php\PEAR;/zend/library
.;D:\xampp\php\PEAR;D:\xampp\htdocs\newsite\zend\library
.;D:\xampp\php\PEAR;D:/xampp/htdocs/newsite/zend/library
.;D:/xampp/htdocs/newsite/zend/library
.;D:\xampp\htdocs\newsite\zend\library
D:\xampp\htdocs\newsite\zend\library
.;./zend/library;D:\xampp\php\PEAR;D:\xampp\htdocs\newsite\zend\library
.;./zend/library;D:\xampp\php\PEAR;D:\xampp\htdocs\newsite\zend\library;/zend/library
.;./zend/library;D:\xampp\php\PEAR;D:\xampp\htdocs\newsite\zend\library;D:/xampp/htdocs/newsite/zend/library
EDIT: Yes, I got all of the above through get_include_path(). I'm on PHP 5.3.8.
Assuming you are not trying to use auto loading, which would be a good idea to rule out problems with auto loaders.
Since the include_path returns ".;D:\xampp\php\PEAR;D:\xampp\htdocs\newsite\zend\library" I would expect a simple include to work.
Assuming you are using ZF2, this test should not error, if the above include path is being returned:
<?php
include ('Zend\Version\Version.php');
If that does error, try it with a full path to verify if it's the include path or something else that is causing the file not to be included.
<?php
include ('D:\xampp\htdocs\newsite\zend\library\Zend\Version\Version.php');
If your test is more complicated that the above, maybe it's something other than the include path going wrong. Can you post the code that is failing?
Also, you might consider installing the ZF2 Skeleton App, which shows current best practices for setting up autoloading, namespaces, etc.
https://github.com/zendframework/ZendSkeletonApplication
While using Zend Library, make sure
1) You have parent dir of Zend folder in include paths
D:\xampp\htdocs\newsite\zend\library has to be in include paths, not D:\xampp\htdocs\newsite\zend\library\Zend
2) PHP not running in safe mode, also PHP is updated to 5.2+ or 5.3+ and if apc is turned on, it must have apc.include_once_override off.
If still not working, inspect by printing get_include_path() or phpinfo();
That should be it.

Functions and classes of PHP extentions in PhpStorm

Are functions of an extension fetch-able for an IDE like PHPStorm when they are given path to php.ini file of extension folder path? I saw that EasyPHP list functions of an extension beside it for those extension that are delivered with it, but it do not display any function for Yaf and Phalcon that is manually installed.
For Phalcon -- get yourself Phalcon Developer Tools ( http://phalconphp.com/download ) -- it contains stub files that can be used by IDE for code completion: https://github.com/phalcon/phalcon-devtools/tree/master/ide/phpstorm
For Yaf -- similar approach (stub file for usage inside IDE): https://github.com/suin/phpstorm-yaf-doc
As this frameworks are php extensions, just make sure, you have configured you php include path in IDE right.
config -> PHP -> and add there something like /usr/share/php (your location)
I use the stubs provided on packagist and install them with composer. https://packagist.org/packages/sneakybobito/phalcon-stubs
composer.json
{
"require": {
"sneakybobito/phalcon-stubs": "1.2.3"
}
}
For compiled extensions you will need a stub file which contains the name of the functions. Since recent versions of PHP include reflection capabilities for extensions[you can get the extension defined classes and functions and then reflect them to get their parameters] they should be possible to generate them.
I'm giving https://github.com/schmittjoh/php-stubs a try but the PHP svn server is down at the moment so it won't run... Will try to check back here later and update on if it works.

Is Zend Framework standalone or part of PHP environment?

Should ZF and PHP have the same path to include in php.ini, or can they be put in separate directories? This is the include path in my php.ini:
;Windows: "\path1;\path2"
include_path = ".;C:\xampp\php\PEAR;C:\ZF\library\"
I couldn't find any Zend documents that specify which, copying ZF\library to xampp\php\PEAR or the entire ZF directory, or using multiple include paths, is recommended for MVC app production. Is there a good practice or does it depend more on not having access to a certain part of a server or if you are using shared hosting, combining PHP and ZF would be the better option?
Should ZF and PHP have the same path to include in php.ini, or can
they be put in separate directories?
It is fine to have multiple directories listed in your php.ini.
include_path = ".;C:\xampp\php\PEAR;C:\ZF\library\"
The following would be better:
include_path = "C:\xampp\php\PEAR;C:\ZF\library\"
In other words, you don't need the "." in your path since anything that needs to be included in the current working directory can be included like this "./path/to/file.php".
Furthermore, you will want to use an autoloader but having the autoloader search ".", is more work than is needed.
Finally, I generally have an include path of:
include_path = "C:\xampp\php\PEAR"
The reason is that since PHPUnit is generally installed via the PEAR installer, I always want that globally available; however, for everything else, I can wait until I have access to a PSR-0 compliant autoloader.
Hope that helps.

Eclipse - PHP Include Path

I´m working with Eclipse 3.4.2 with PDT.
I´ve added some libraries in the applications folder, and add that folder to the PHP Include Path.
When I run as script, it works perfect, but if I access the page outside eclipse, the libraries are not accesible, i need to add this line:
set_include_path(
implode(PATH_SEPARATOR, array(realpath('../application'), get_include_path(),))
);
Is this necesary? how can avoid this?
You may also specify path in include() statement, but it's not very convenient.
Also, you may specify corresponding include_path value in php.ini configuration file (see here for details), but usually this directive contains path to system-wide libraries, not application-specific paths.
If you are using OOP, you may implement your own class-loader, which will look for classes in specific directories. See this article for details.
Yes. It is necessary. Because PHP interpreter should know, from what folders load libraries.

Adding functions to PHP core

I have several functions that I wrote and I use regularly on my servers, is there a way I can add them to the core so I don't have to include them from external files?
I am running PHP5
You could add your libraries as a PEAR extension. Then you could add it to your local PEAR repository. Pear is added to the default include path in php.ini. Then you can just use "pear install myextension" on your machines.
If these are C functions you interface with in php (php extensions) then you can do something similar with PECL.
I've done this before.. it's a fairly involved process, but not too bad. This article at zend.com should tell you everything you need to know:
http://devzone.zend.com/303/extension-writing-part-i-introduction-to-php-and-zend/
edit: I should add that there are better ways to achieve the essence of what you're trying to do. Remember that doing this will further clutter up PHP's (already very cluttered) namespace. You're probably better off just making a global include file that has all of your most commonly used functions that you include wherever you need it.
edit2: Upon rereading your original question, you said you don't want to do that, but I still think it's probably the best way. But best of luck to you with the extension route.
If you want your function to always be available, without including it, do this:
Create your function in an php file.
In your php.ini search for the option "auto_prepend_file" and add your php file to that line, like this: auto_prepend_file = "/path/to/my_superglobal_function.php"
Or if you write without a path like this: auto_prepend_file = "my_superglobal_function.php" It will look in your include_path in php.ini to find the file.
Why exactly is it so hard to include the files where you need them?
I suppose the auto_prepend_file PHP.ini directive could work. But it's not really recommended.
If you got autoload, you can move the functions as static methods of a class like My_Functions.
Or for dividing it into more files you can use My_Functions_Math. Then you will only need to load the functions you need. And with autoload you don't have to worry about including files.
You cant autoload namespace functions, so if you want to use autoload the functions have to be static methods in a class. But you can use namespace to make it easier to fx replace the class in the future and/or shorten the long class name. Example:
use My\Functions\Math as Math;
Math::calcThis($i);

Categories