I would like to override the _() PHP function so that it supports one or more arguments. Is it possible to do that using PHP code?
No, but with PHP version >= 5.3.0 you could use namespacing though.
It is possible, using the Runkit extension.
However, it's generally not considered a good idea, except for use with things like unit testing, where you may want to isolate some of your functionality.
For general use, you shouldn't be overriding built-in functions because it makes your code harder to maintain, and opens you up to some very hard to debug issues.
Also, the Runkit extension is marked as 'experimental', which means it really shouldn't be used in a production system.
You could try the runkit extension but it's considered a bad practice in production environments. See also Redefining PHP function?
Really don't do this! Even if you are the only developer on this project and know that your project won't be successful, one can never know how long your code will be in use (often much longer than you would think). Should another developer have to dive into your code, he will have a very hard time, because he/she cannot rely on PHP itself.
A better way would be to write your own methods/functions, which then call the PHP function you want to overwrite. This way a developer immediately can see, that this is not the standard PHP function, and even if PHP will allow other parameters in future versions, you will have a clean solution.
Related
I'm discovering Php and it's Oop implementation and wondering if there is really an practical utility of using Interfaces when we use a non compiled language and when errors can only be discovered at execution time. Am in missing someting?. Another point is that I didn't find any extension or plugin for editor or Ide which forced implementing the Interface when creating a class which is for me the essential point because Interface are really useful when working with others and functionals requirements. So that make me thinking that we need to know the contracts of the Interfaces before using them..
I didn't find any satisfying reading about these question and hope someone would give me some clues...
As my Questioning were on the way I can be sure of following the contract implied by an Interface I had a look on the differents Ide or extension (I'm using mainly vscode)and now what I understand is I rely on their functionalitie about continuous code validation. For example Dev Sense PHP tools for Vs Code do the job but normal Php Intelliphense doesn't.
If I don't use an Ide or extension with this code validation I will have executing time errors if I fail to execute the whole Interface contract.
I'm writing a PHP extension (although its starting to look a lot like a zend extension). There are instances where it needs to write to a logging interface.
I see that zend_error() is being used elsewhere however:
reading the source code on github I found zend_error declared in zend/zend.h but I couldn't find the corresponding definition of the function
looking at the contexts in which zend_error is used, I suspect that calls will be rerouted/diverted by set_error_handler
Normally, the logging will happen in MINIT and MSHUTDOWN (where presumably an error handler defined by a script cannot have any influence) but there may be times in between as well - and I'm looking for some consistency. Hence trying to understand how the mechanism works.
Is it safe to use zend_error() in MINIT/MSHUTDOWN?
How do I ensure that I am always calling the the default error handler?
Well, I found this in the PHP Wiki. I think this is old, but I imagine it still applies to Zend3:
Don't use zend_error
zend_error() should only be used inside the engine. Inside PHP
extensions only PHP's error functions shoudl be used. Typically
php_error_docref() is the best choice. php_error_docref() will extend
the error message by extra information, like the current function name
and properly escape output where needed. zend_error() is used by the
Zend Engine due to PHP's modular architecture where the Zend Engine
and TSRM should be compilable without other parts of PHP. The engine
therefore can not use PHP level APIs. This limitation does not exist
in extensions.
What this says to me is that zend_error was written for use in the engine and not designed as one of the tools for use in building extensions. For that reason, you are unlikely to find documentation covering the details you are asking about, and, even if it DOES work reliably for you, it may not continue to do so.
I'm writing a Wordpress plugin, so it's going to be used by different users and different PHP versions. The problem is that I found that some of the functions (like json_encode) are available in PHP 5.3 and not in PHP 5.2 or less. This creates a big issue, as most users don't have the latest version.
I want now, after getting the plugin 99% done, to do the following
Test my code with some kind of an app. where I can put the minimum PHP version. That App. or program would find out functions like json_encode. Not sure if that is possible, but would probably solve most of my problem.
Is it possible to get the native code of the PHP functions in PHP. I'm not sure if they are written in PHP or not, if so where can I get them. If not, what's the best option to find replacement for these functions. Certainly, I don't want to be re-coding them from scratch
What's the best methodology to implement the functions. I found some developers that check for the PHP version, while others check if the functions exist. Which one is best and why?
Would love also to read about your deployment strategies and how you dealt with that particular problem.
2.Nope. They're provided by compiled extensions written in C. For json_encode (which BTW is available since 5.2 not 5.3) you can use Zend_Json as an alternative
3.Checking if function exist is the best if you want to be 100% sure. After all, one can be running a self compiled version of PHP with not all core functions available. Check PHP version number, to know if features like namespaces, exception chaining etc are available.
You can use PEAR's
PHP_Compat to provide missing functionality for older versions of PHP and
PHP_CompatInfo to find out the minimum version and the extensions required for a piece of code to run
If you want to provide your own userland implementations of functions or classes, you are good advised to provide them wrapped into function_exists or class_existsblocks, so they dont interfere with PHP versions providing those methods.
I don't really know how Wordpress plugins work but except if you really want your to be able to run on old PHP version, you'll need to check for available function and provide an alternative, which can lead you code to be messy.
If you can, and want to educate your users, you can simply version_compare() function to compare version against a well tested and fully functionnal PHP version and throw a educationnal and explicative message to your end users.
if (version_compare(PHP_VERSION, '5.3.0') <= 0) {
echo 'You need to run PHP 5.3.0 to use this plugin';
}
Re 1.) there may be such an application, but there also may be not. What you usually want to do is to keep close tabs on each function you use in the manual, which states what PHP version(s) are needed.
Re 2.) if a function is PHP 5.3 or 5.2 only, you will usually find a replacement suggestion in the User Contributed Notes or on Stack Overflow. (Be careful what you use though, a lot of the code in the UCN is bad - but in that case, there is usually at least one comment saying so.)
Re. 3.) it probably doesn't matter, but checking for whether a function exists is surely the safest way.
There are a hell lot of inbuilt PHP functions. I was wondering that after almost 2 and a half years of working as a software engineer I hardly use a little fraction of those. But all of them are defined and can be used with the default PHP installations.
I read somewhere in SO that PHP provides all these inbuilt things but doing similar things with languages like JAVA needs a lot of coding. Is that correct? I am not experienced in other languages much.
Also, am I correct to assume that a large portion of these functions are not used by any of the other inbuilt functions or anything (internal dependencies)? E.g. these functions pdf_fit_table(), gzopen() are needed only in case of PDF and gzip file related things respectively.
If so, then as advanced programmers, does PHP provide any option to us to selectively load them, based on the specific project requirements or more dynamically, based on a specific module? e.g. load PDF related functions only if I have PDF related tasks. If possible, at what level can it be done? If at the PHP installation level, then I think it is not possible in case of shared hosting. Is a better solution to this possible?
I am just speaking from a common sense point of view, we include files containing functions on a need basis.
Is it going to give a performance boost?
I am not much aware of the core libraries etc. of PHP. So, please shed some light.
Updates:
Thanks for the answers
#pygorex1 - The HipHop way is to optimize PHP overall. So, putting in very simple terms, if I am correct, if it was taking 1 second to run before then using HipHop it may make it 0.7 second. But in both the cases, the presence of those extra unnecessary defined functions are adding their overhead (say 0.1 second in first case and 0.07 sec in HipHop case). If so, then HipHop targets something else and does not answer my question. However, the other two points you gave say that all has to be done while compiling. So, it probably means if I compile with an extension then the function groups under that will be loaded every time . Then probably there is no further way of removing the inclusion? Some kind of everride?
#Tyler - I agree that it might be difficult to do what I am asking for but the reason is not what you are saying. It cannot be so difficult to find out the dependencies. Just applying common sense, I can say that functions like is_numeric(), is_array(), array_walk(), func_get_args() etc. are very basic ones and are probably called by many but there are easily distinguishable groups like the socket functions group containing e.g. socket_connect() which need not be included if not explicitly needed. The problem probably is that it needs to be specified while compiling, like pygorex1 has answered.
Concerning any potential performance boost - you're probably not going to notice it unless you're serving a ton of dynamic PHP pages. This road has been traveled before - take a look at HipHop, Facebook's tool to optimize PHP into C++. Utilizing byte code caches like APC and eAccelerator AND/OR rewriting your PHP code to cache intelligently with memcached will improve PHP performance far more than enabling/disabling certain PHP functions.
That having been said, there's two main ways to pare down the number of functions that PHP has available:
PHP compile-time options
Available when compiling PHP from source. One of the functions noted in the question gzopen() is part of the zlib extension and has to be enabled at compile time. There's quite a few built-in compile-time options.
PHP modules
These are loaded dynamically by PHP and are controlled by the php.ini config file under extensions - they are .dll files on Windows or .so files on Linux. A snippet from my development php.ini:
...
extension=php_bz2.dll
;extension=php_curl.dll
;extension=php_dba.dll
;extension=php_dblib.dll
extension=php_mbstring.dll
extension=php_exif.dll
extension=php_fileinfo.dll
extension=php_gd2.dll
...
There is dl() to load a PHP extension at runtime.
Example to load an extension dynamically:
if (!extension_loaded('sqlite')) {
$prefix = (PHP_SHLIB_SUFFIX === 'dll') ? 'php_' : '';
dl($prefix . 'sqlite.' . PHP_SHLIB_SUFFIX);
}
This is taken from http://php.net/manual/en/function.dl.php
The php function namespace debacle, is, well, exactly that.
No, there's no way selectively load them at run-time. Just because you don't call something, doesn't mean something you call doesn't call it.
Dont bother compiling out built-in functions. Learn about shared libraries and linux caching system. Those files(and functions) are basically always loaded and cached so it has very little impact on an application. As pygorex1 said, its better to use a good caching mechanism than crippling the PHP distribution on purpose.
#powtac: doing dl() as a way to dinamically load some libraries might acually slow down your app(depends on how many dl() you do, it might be better to have them always loaded in memory than loading them on request)
#Tyler Eaves: you may disable some function from being called actually. There's nothing preventing their loading though..
Also, hip-hop as far as i knwo actually compiles php code down to C/C++ code, and then compiles it. This has the BIG advantage of skipping the virtual machine, and php-specific upcodes and lots of overhead over a scripted language, but has the big disatvantage that its not a scripted language anymore.
I have a PHP class I want to convert to a PHP extension. I checked some tutorials (tuxradar's writing extensions, php.net's extending php, and zend's extension writing) and it's a bit complicated.
I found the article "How to write PHP extensions" (ed note: site is defunct) and I wanted to know if it is possible to use this to make it grab a PHP class from a certain path (say /home/website1/public_html/api/class.php), execute it and return the class instance.
This way it will be usable in other websites that are hosted on the same server – each can simply call the function and it will obtain its own instance.
Is that possible?
The question as I understand it now is, The user has a PHP class that they would like to share with multiple people, but does not want to share the source code.
There are many solutions to this, they generally invovle turning the PHP code into some kind of byte code, and using a PHP extension to run the byte code. I've never used any of these solutions, but I'm aware of the following:
phc is an open source compiler for PHP
Zend Guard
HipHop for PHP - I'm unsure about this, but Facebook recently released it so it might be worth a look.
I'm sure there are others. Just Google for PHP Compiler, or PHP Accelerator.
In one sentence: I don't believe so, I think its a lot more work than that.
No, there is not tool that can do that.
Anyway, what you want call be easily accomplished with auto_prepend_file. Just make that ini directive point to a PHP file that has the class definition, and then it will be available to all the applications.
If you don't want the users to be able to use the source, you can use one the several zend extensions that allow you to pre-compile the file and use it in that form.
You can extend underlying C library functions into PHP space by writing PHP extensions. However, i think in your case you don't need to write one.
I am aware that this is an old question (being from 2012) however the answer has changed and there is now a tool that can do this. Jim Thunderbirds PHP-to-C Extension toolset provides the means to take a simple class in one file all the way up to a complicated multi file multi-level namespaced framework and convert it to a C-extension that can then be installed into your PHP server.
While in many use cases doing so is not needed as the ordinary PHP code will work just as good in some cases significant performance improvements can be experienced. The information page shows that an ordinary class (deliberately designed to take a long time) took 16.802139997482 seconds as plain vanilla PHP, and 3.9628620147705 as a PHP extension built using the tool.
As an added advantage the tool also provides an additional feature. The ability to combine PHP code (to be converted to C) and native C code within the same extension which can produce even greater performance enhancements. The same example used above only tool 0.14397192001343 seconds when much of the intensive code was moved to a bubble sort C code and simply calling it from within the PHP code.
As a side note functionally to the end developers using the code using the extension is very much similar to having the files manually included in the PHP file being developed except it doesn't have to be specifically included as it is done through the PHP extensions component.
(Disclaimer: I am not affiliated with this developer but am glad to have come across it as it is thus far working for converting some of my intensive classes into PHP extensions without needing to know C).