Can the json extension be disabled in PHP? The doc says that:
As of PHP 5.2.0, the JSON extension is bundled and compiled into PHP by default.
But some people in the comments say that the json extension is sometimes provided as a separate package.
Can the json extension be explicitly disabled, or can we be confident that it's always available?
Background: I want to make a class in a library of mine implement JsonSerializable, but that may be a BC break if the interface is not always declared, and the library suddenly relies on an extension that's not always available.
PHP 8:
No, the JSON extension cannot be disabled anymore.
PHP 7:
Yes, any PHP extension can be installed, uninstalled, enabled, or disabled at will.
The json extension - despite its ubiquity - is still just an extension and can be removed in this way as well.
There are a couple of cases in which the json extension might not exist:
The administrator disabled/uninstalled it:
;extension=json
The version of PHP that was installed was compiled from source manually, and the json extension was left out:
--disable-json
The extension is bundled as a separate package; for example, on Fedora you have to install the php-json package explicitly.
The important part of your question: Can we be confident that it's always available
Normally, I would say no. However unlikely the case is that this particular extension is disabled or left out, it still doesn't mean that it won't happen.
If your intended audience is limited to people who probably wouldn't touch those kinds of settings, then you might be safe, but there's no guarantee.
My suggestion: Build your library as a Composer package, and declare ext-json as a dependency. That way, you can provide installation instructions as a Composer package and if the underlying system doesn't meet your package requirements, the installation will fail and the user will be alerted to the missing extension.
Related
I tried to import data from XML file using the importDump utility...
root#aace30d9b5f3:/var/www/html/mediawiki-1.36.1# php ./maintenance/importDump.php mrwiki-latest-pages-articles-multistream.xml
Got this error:
MWException from line 2108 of /var/www/html/mediawiki-1.36.1/includes/parser/Parser.php: PCRE needs to be compiled with --enable-unicode-properties in order for MediaWiki to function
I downloaded the source code of PCRE and run make / make install but that did not work. I am using the official docker image of mediawiki if that matters.
https://hub.docker.com/_/mediawiki
update:
I need to simplify what I am trying to ask...
Is PCRE compiled using --enable-unicode-properties in this dockerfile?
https://github.com/docker-library/php/edit/master/7.3/buster/apache/Dockerfile
Is that php image being used by mediawiki official repo?
https://github.com/wikimedia/mediawiki-docker/blob/51105612d2e1168f1b0545f47951847d63fb9613/1.36/apache/Dockerfile
PHP, unfortunately, usually uses its own PCRE library (from the manual: "By default, this extension is compiled using the bundled PCRE library"), as you can also see in this other answer.
What you need to do is recompile PHP itself in order to activate the PCRE changes. To do this you need to (you can do this on a cloned machine)
check out the exact PHP version
download and install the relevant source packages
get the exact compilation options from phpinfo()
change the PCRE options appropriately
make (you don't need install as you're not going use PHP in the cloned machine)
The only file that you need to change now is the basic PHP binary (/usr/bin/php, watch out for alternatives symlinks). If you used a cloned machine with the same distro and versions, you can easily rename that one binary on the original machine and move in the new one, and it will work (I've done this dozens of times), so you'll have the option to go back at any time.
Or you can install the development packages for PCRE on the cloned machine and supply --with-pcre-regex= and --with-pcre-dir= to the compiler. The new PHP binary will now use the system PCRE, so that pcretest -C will now yield reliable results. I am not sure whether you need the same PCRE version on both machines (you probably need the same major version, but a minor version mismatch shouldn't be a showstopper). Be aware that updating the system PCRE library might break compatibility with PHP if for any reasons the library calls change.
I want to install mailparser extension.
I downloaded php_malparse.dll ( put it to php/ext folder).
Also added : extension=php_mailparse.dll to php.ini
But it doesn't work, and php_info() doesn't show it too.
In logs I get:
PHP Warning: PHP Startup: Unable to load dynamic library 'E:\xampp\php\ext\php_mailparse.dll' - %1 \xef\xbf\xbd\xef\xbf\xbd \xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd \xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd Win32.\r\n in Unknown on line 0
I need help, how can I solve this problem?
Thanks!
It's difficult to say what's going on here. Typically the message Unable to load dynamic library means the library (in this case on Windows the .dll file) is not correctly formatted and the OS was unable to map it into memory or PHP was not able to use it.
Some possible reasons include:
The extension was not compiled for the same architecture as the target PHP build (e.g. the PHP is x86-64 but the library is x86)
The extension was not compiled using the same runtime version; PHP is pretty strict about this (e.g. PHP5 is built with vc11 on Windows, PHP7 is built with vc14, ETC.)
The extension was not compiled against the same version of the PHP API or extension API used by your PHP build; typically PHP will show a more-detailed error message when this is the case (it's strange that your error message contains a bunch of non-printing characters though...)
To double-check all this, view a dump of phpinfo() to see what kind of PHP you have. Look for the PHP API and extension versions as well as the system architecture and whether thread safety is enabled. Then return to where you downloaded the php_mailparse.dll extension library and make sure the extension aligns with your PHP build. Here are some official instructions for this process for Windows PHP extensions.
I found official builds of this module here. There are a lot of different choices to pick from. Pay attention to ts (i.e. Thread-safe) vs nts (i.e. Non-thread-safe), x86 vs x64 (i.e. the architecture) and vc11 vs vc14 (i.e. the runtime version). You may have to experiment until you find one that works for your PHP build.
It might also be worth checking out the official install instructions for the mailparse extension. Note especially that the mbstring module has to be loaded first for it to work.
Using Homestead, I try to run the BIGINT example #5 from the PHP docs and I get an "Integer overflow notice". The flag JSON_BIGINT_AS_STRING is ignored, and the result is invalid (a maximum bigint of 9223372036854775807).
The Homestead instance has the following software stack:
PHP 5.6.9
JSON 1.3.6 with JSON-C headers and lib 0.11.99.
I then tested it on 3v4l, and it works. I don't know their JSON setup.
I then tested it on OS X's pre-installed PHP which is:
PHP 5.5
JSON 1.2.1 and no JSON-C headers/lib.
This works, too - just like in the docs.
Subsequently, I found this issue which leads to this commit and seems to be what's causing the problems here, but why does Remi invalidate >64bit numbers and call integer overflow, despite the default JSON extension (present on 3v4l and OS X natively) not doing that? Doesn't this violate the claim that it's a "drop in replacement"? In its current state, this extension, which is included by default in many installations, goes directly against PHP's official documentation.
Are there any good solutions for this that don't require internal alteration of libraries used, like Guzzle?
Edit: Upon searching further, I have found this which confirms that one developer's opinion is the cause of problems here.
Yes, it's really just Remis opinion here. That way it clearly is not a 100% drop-in replacement. You ask why it's allowed? Because nobody can disallow a free developer to write his own code the way he wants.
So… all you can do is complaining and compiling ext/json yourself (instead of using JSON-C).
That means cloning from php-src source (https://github.com/php/php-src), checkout PHP-5.6 branch, navigate into ext/json directory and compile via phpize && ./configure && make install. Then add that extension to your php.ini instead of the json-c extension. [If necessary, you may need to first install some compiling tools...]
Note that with PHP 7.0 the json extension is replaced by a new implementation (see also the RFC: https://wiki.php.net/rfc/jsond), which doesn't have these issues and additionally has no license problems.
I have an inconsistency, and I could not align their versions properly, so I just wanted to remove the library version. Can I do this? Is the header version for PHP while the library is from my distro? Can I upgrade PHP's library version? If so, how? I am using PHP 5.4.4
For example,
Is the header version for PHP while the library is from my distro?
It means it was compiled against the 1.0.1 headers, but is now dynamically linking against 0.9.8. So you are using an older version than what was used when PHP was compiled.
Many libraries store the version in the header files. So when a program uses the library, it can do something like int HEADER_FOO_VERSION = LIBRARY_VERSION, which embeds that version number into the program (e.g., php). Now when that program runs, it links dynamically against the library, which may be a different one than was on the host system.
That library may have a function call, say int get_library_version(). So the program (PHP) can check if HEADER_FOO_VERSION == get_library_version(). If it's different, then there could be a compatibility issue. (Of course, it doesn't have to be assign to a local variable... I'm just trying to drive home the point that the header version number can be compiled into php, and remains constant no matter which version of the library is being used at run time.)
Whether or not it is a problem depends on if the two versions are compatible.
Usually if the library is > than the header, you are okay. It's definitely more likely to be a problem if the library is older than the version it was linked against. Of course, this is because it's impossible to know what changes future versions may have.
So in your case, I would try to update your system's SSL libraries via apt-get, yum, etc, to match the version PHP is expecting.
To check which version php is using on Linux:
$ ldd `which php` | grep ssl
libssl.so.1.0.0 => /lib/i386-linux-gnu/libssl.so.1.0.0
Note that which php is just a short-cut to find the full path. You can hard code any executable you'd like to check: ldd /usr/sbin/httpd.
I dont know the answer myself, but when searched on google some nice resources explaining the same.....
What's the difference between a header file and a library?
The version of the files are the one mentioned in the phpinfo used to create a library.
Hope it helps, there are lot of resource available if searched on google.
Still will like to hear from someone in great details about the question
The header version is the functionality version, whereas the library version is the code version.
The header defines the interface - it tells you what functions are within the library. If a header gets updated, then you need to check to make sure all the functions are the same, and see if any are added or subtracted.
But if a library gets updated, and not the header, it means all the function calls are the same, but some of the code may be changed (eg, bug fixes).
In your example, PHP is seeing functionality for OpenSSL 1.0.1, but the actual version of the source code that OpenSSL is loading is 0.9.8o
This is commonly seen on updated versions of openssl. What happens is the newer versions for the libraries are stored in different folder. The original folder located at /usr/bin/openssl would need a symbolic link to the new folder /usr/local/bin/openssl. That would get both to be the same version or just show OpenSSL Version _(Whatever)
Normally there is no concern for this, since it still works the way it is intended. This is seen a lot on shared servers.
EDIT:
The information in this post is generic and can be different if you are running
CentOS, RedHat, Ubuntu, or another Linux/BSD version. Check documentation or man
pages for the best information
If you do update your OpenSSL, some versions of *nix Require for you to rebuild PHP and Apache for it to update
If you are rebuilding PHP from source, I have found another possible reason for a mismatch. It's so simple yet if you are not familiar with building from source on Linux, not knowing it can cost you a lot of time.
The answer is here: https://serverfault.com/a/567705/305059 - unfortunately I cannot up-vote it over the not-so-useful answer, so if you have the reputation there, please do.
You need to run "make clean" before "make" in order for it to rebuild all binaries. Strangely, without this step I was getting an updated library version, but the old header version - so I think it must have rebuilt something, but not everything. My rebuild involved linking to a version of curl in another location (built with ssl), which might be the reason behind it.
Anyway, I hope this helps someone. Thank you to #velcrow on serverfault.
I have the source for a PHP extension, and the compiled version for PHP 5.3. But I have PHP 5.4, and the project appears to have been abandoned.
So given the source code, what is the minimum I have to do to compile it for PHP 5.4?
EDIT Note: I'm on Windows.
It depends on the extension itself. If the extension requires some other libraries, like, say the mysql extension, then you also need the mysql client library - the C API. Why? Because you explicitly stated that you want minimal dependency requirements. If the extension does not require any other libraries, you can nicely open those C files that you already have, and compile it using any available C compiler. Naturally, you will need PHP development kit as well. :)