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.
Related
I'm going through the PHP manual and found the word 'userland' a couple of times. What does that usually mean? I found it in this page; I think it's the source code itself but I'm not sure.
From PHP manual:
While executing in a debug environment, configured with --enable-debug, the leak function used in the next example is actually implemented by the engine and is available to call in userland.
Since this question does not have a correct answer yet (despite an answer being selected), I'll go ahead and answer this.
The PHP core development team makes three main distinctions when referring to PHP:
PHP core. This refers to the Zend engine that powers PHP. It does things like tokenize userland code, handle memory management, process built-in keywords (if-else, while, isset, etc), and more. That last bit is why built-ins are many times faster than function calls. What PHP core generally does not do is implement functions like substr(), fopen(), etc., which is left to...
PHP extensions. This refers to the majority of the PHP source code but also PECL extensions and other PHP extensions written in C (and sometimes C++). All of the core functions and classes that are always available with PHP are actually implemented in extensions with the biggest extension being 'ext/standard'.
PHP userland. This refers to code that users of PHP generally write that leverage various PHP extensions and the core.
When you see the phrase "pure PHP userland" usually in reference to a PHP userland library that someone writes, they generally mean without dependencies on anything outside of PHP built-ins, extensions that may not be compiled in or available on a host, or external software not in the PHP ecosystem.
The use of any of these phrases may be an indicator that the person tends to lurk on the PHP internals mailing list. Most PHP developers are userland devs and have little to no knowledge of the inner workings of PHP itself.
It's not a PHP term, but a general computing one:
The term userland (or user space) refers to all code which runs outside the operating system's kernel.
https://en.wikipedia.org/wiki/User_space
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.
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).
I'm trying to accomplish a task and turns out that the code I need is packaged as a PHP extension, which according to what I've been told means I have to have root access to install it (I'm on shared hosting so that's a bit of a problem.
I'll solve this problem later, but for now I'm trying to understand the difference between an extension, a library, and a class. Is it more of a packaging thing that could be overridden and repackaged a different way, or is there a valid architectural reasoning behind it?
Also when releasing your own code, what makes you decide to release as library vs. class vs. extension? or do you go with whichever sounds better?
thanks in advance.
P.S. If you must know which extension I'm talking about, it's Libpuzzle, but that's really beside the point, my question is more general.
An extension is a pice of code programmed in C which will be included into the PHP core when PHP starts. Normally you have some more native functions available after including a extension. For example a zip functionality.
A class is a abstract pice of PHP code which solves common tasks. For example sending emails. You can find some common classes at pear.php.net.
A library is a collection of PHP classes wich solve more generic tasks for example buliding HTML forms AND sending emails. The Zend Framework is a framework which consists of many, many PHP classes.
Normally extension features can be programmed in PHP. For example the PEAR::Compat class. Often you will find the functionality you need as a PHP class available. I'm sure the stackoverflow readers will supply you with ideas where to find a specific PHP class.
Extensions are low-level. Usually written in C/C++, and compiled into native-code shared libraries, they interact with the Zend Engine directly. It has pros and cons, main advantages being the speed and more control; and main disadvantages - they are harder to install, and require compilation (and that requires a compiler and PHP headers); it's not true they require root access though - you only need ability to use custom php.ini (or dl() function, but I see they deprecated it for some reason).
Libraries/classes are high-level and interpreted. If you don't know if you need to write extension, then you probably don't. About what classes are - read about OOP. A library is a reusable collection of code (most commonly in form of functions/classes).
Some libraries (including libpuzzle) also include a command-line tool. So if you're unable to use the PHP library due to your shared hosting environment, maybe you can compile the command-line tool. Then you can run it from PHP using something like exec. It will be slower and require more memory than a library, but it might get the job done. Of course, many hosts also have restrictions on commands like exec, so this might not work either.
I'm writing an interposition library to track the usage of some library functions in libc, such as open(), close(), connect(), etc. It works generally well on most of the applications. However, when I try it with PHP, using PHP's MySQL module in particular, none of the function calls to libc inside this module is been tracked (so no connect(), no socket(), etc.). 'strace' told me that the system calls socket(), connect(), etc., took place. Running 'file' on the module and libmysqlclient.so.16.0.0 said that they are all dynamically linked. So it shouldn't be a problem caused by static linkage. What might be the problem?
I'm using Fedora 11 64-bit version.
Thank you.
It seems like that it was not caused by static linkage. In fact, PHP is dynamically linked to other libraries. The problem relies in the way PHP loads extensions.
PHP loads extensions by calling dlopen() with flags RTLD_LAZY, which means that the symbol will only be resolved when the reference is executed. This bypasses the interposition specified by LD_PRELOAD.
It's possible that the library may be invoking system calls directly for some reason. In this case you'd need to use strace (or ptrace() in your own program) to track this usage.
I agree with the answer above that these libraries may be bypassing the calls to open(), write(), etc in libc.. In other words, those libraries may be calling the system calls directly using assembly and not using the libc interface.. although it is not all that common to see applications using the syscalls directly, it is not unheard of..
If that's the case, that's why you would not see any interception in your library interposition experiment.. You have two ways then, the quick one through strace and the more complex one in building a kernel module that will intercept these calls at the kernel level and reporting to whatever framework you are building..
Have fun..
ErnestoB