Make App Engine for PHP load BCMath or php.ini - php

I'm running the latest php-cgi from Arch Linux's repos. I enabled the BCMath module on php.ini and it works when I run php, php-cgi and php in Apache. However, when dev_appserver.py runs php, somehow it loses the configuration I set in php.ini. Causing both BCMath, soap and my locale settings to not load, causing:
dev_appserver.py --php_executable_path /usr/bin/php-cgi appengine-try-php
PHPEnvironmentError: The PHP runtime requires the "bccomp" function, which is not defined.
php-cgi -i | grep -i bcmath returns BCMATH enabled.
php -i | grep -i bcmath returns BCMATH enabled.
php -r "echo bccomp('1.0001', '1', 5);" returns 1.
Is there any way to make dev_appserver.py load the module or php.ini?

Here's the code that fails - we check if the function exists.
if (!function_exists('bccomp')) {
echo "The PHP runtime requires the \"bccomp\" function, which is not ";
echo "defined.\n";
echo "If you built PHP using \"configure\" then please rebuild with:\n";
echo ' ./configure --enable-bcmath';
exit(1);
}
I don't know why you'd have the extension enabled but the function not existing. Probably try listing the functions that are available to double check it's there.
php -r 'print_r(get_defined_functions());' | grep -i bccomp

google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/php/runtime.py
Supports loading a php.ini file from the project directory, as such you can just drop a php.ini file in the project directory. It will by default ignore the php.ini file in /etc/php/php.ini unlike all other instances of php. Here is the php.ini script I'm using. It likely has extra modules and modules that are missing compared to the production App Engine.
date.timezone = America/New_York
extension=bcmath.so
extension=bz2.so
extension=curl.so
extension=gd.so
extension=gettext.so
extension=mcrypt.so
extension=mysqli.so
extension=mysql.so
extension=openssl.so
extension=pdo_mysql.so
extension=soap.so
extension=zip.so
Happy Apping.

Related

Is there any way in php to check if the extension is zend_extension before loading it

Before adding the extension to php.ini file using a php script, I want to check if the extension is a zend extension just to avoid the error that happened when I load it as normal extension.
Interesting question, and it still needed and answer.
You can check a PHP extension (a shared object file on linux)
is a zend extension and
it can be loaded from a specific PHP version from the CLI SAPI [doc].
Here a shell example asserting that a compiled .so file can be loaded:
php -n -dzend_extension="$PWD/modules/xdebug.so" \
-r 'echo implode("\n", get_loaded_extensions(true)), "\n";' \
| LC_ALL=C grep -i xdebug
This (complex) shell command returns non-zero when the file ./modules/xdebug.so does not result in having PHP the extension named "xdebug" (case insensitive).
If you need this within a PHP script, you could use passthru() [doc] or exec() [doc] with the $result_code out-parameter.
For example to test before installing the file in the extension directory [ini] and activate it in the ini.
On standard error you'll find as well diagnostic messages when it fails to load.
E.g. loading a zend extension for PHP 5.3 with PHP 5.6:
$ php5.6 -n -dzend_extension="$PWD/modules/xdebug.so" \
-r 'echo implode("\n", get_loaded_extensions(true)), "\n";' \
| LC_ALL=C grep -i xdebug
Failed loading /home/hakre/install-php5.3/xdebug-2.2.7/modules/xdebug.so:
/home/hakre/install-php5.3/xdebug-2.2.7/modules/xdebug.so: undefined symbol: php_body_write
$ echo $?
1
Some remarks:
The -n switch reduces side-effects from configuration, it disables standard ini loading completely leaving you with the compiled in default values (you may want to run it as well without, it might show more zend extensions then).
The $PWD [posix] is for the current working directory, it is best to pass an absolute path to the zend_extension directive on the command-line (-dzend_extension=<extension-path>) as with a relative path PHP will look as well in different directories if loading fails where you just want it to fail (or succeed) with exactly that binary extension file in the first place without any more look-ups.
This should give enough pointers to cover cases like upgrading an existing extension as well. It won't take the burden off you, e.g. in migration situations, to compare as well changes in an extensions ini configuration. Just saying.

ionCube Loader, returning empty screen

I am attempting to install ionCube on my VPS from DigitalOcean and I have ran the install and selected the appropriate options but then it simply returns a screen with the header of ionCube but then it has a banner saying "IMPORTANT: Ensure that This Script Is Removed When No Longer Required" followed by a single line of writing that says "ionCube Loader Wizard" and does nothing. In addition the application that it using ionCube says it is still not installed.
The empty Wizard page might indicate that a few PHP functions are disabled, though without the output of your phpinfo(); I can only guess.
DigitalOcean themselves have instructions on how to install the Loader, which can be found here. These are applicable to most VPS with slight alterations. A rough summary in case the link isn't available:
Get and unpack the newest Loader on your server: (if you are not on DigitalOcean please choose your own Loaders here)
32bit:
wget http://downloads3.ioncube.com/loader_downloads/ioncube_loaders_lin_x86.tar.gz
tar xvfz ioncube_loaders_lin_x86.tar.gz
64bit:
wget http://downloads3.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz
tar xvfz ioncube_loaders_lin_x86-64.tar.gz
Find out your extensions directory:
php -i | grep extension_dir
Which will yield something like
extension_dir => /usr/lib/php5/20090626+lfs => /usr/lib/php5/20090626+lfs
Copy the Loader to the extensions directory:
PHP_VERSION=$(php -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;")
sudo cp "ioncube/ioncube_loader_lin_${PHP_VERSION}.so" /your/extensions/dir
For example with the previous output:
PHP_VERSION=$(php -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;")
sudo cp "ioncube/ioncube_loader_lin_${PHP_VERSION}.so" /usr/lib/php5/20090626+lfs/
Add the zend_extension entry to your php.ini. This step is not described in the DigitalOcean tutorial, it seems that their PHP is set up to load any extension in the extensions directory I assume, so this might not be necessary for you.
Find out where your php.ini file is (or better yet, plugin directory):
php -i | grep "Loaded Config"
php -i | grep "Scan this dir"
You will get something like this:
Loaded Configuration File => /etc/php.ini
Scan this dir for additional .ini files => /etc/php.d
You can either add this entry to the top of your php.ini (in this case in /etc/php.ini), or add a new file 00-ioncube in your ini directory (in this case /etc/php.d/00-ioncube with this content:
zend_extension = "<path to your ioncube loader>"
As an example with PHP 5.5 and the previous path:
zend_extension = "/usr/lib/php5/20090626+lfs/ioncube_loader_lin_5.4.so"
Restart your webservers:
service apache2 restart
service php5-fpm restart
Do remember to delete the ionCube Loader Script you installed from your server, since this might pose a security risk if left on the server.
In case something goes wrong, check the output your phpinfo();, verify that you have the correct Loaders installed (pay attention to thread safety, architecture and PHP version) and get the Loaders manually from here, and again make sure to choose the right one.
If it still does not work, check your error.log (typically in /var/log/apache2/error.log or /var/log/httpd/error_log) to see if the Loader is being picked up. The ionCube Support is also available should there be any problems.

PHP extension installed but not loading

I'm trying to install php's ssh2 extension, and having a little bit of difficulty. The file is there, it's just not loading into php.
First, I've installed ssh2 with:
aptitude install libssh2-1-dev libssh2-php
(For what it's worth, I'm running Ubuntu 12.04 on Nginx.)
I can see that ssh2 is loaded using the modules command:
php -m |grep ssh2
ssh2
However, when I run my code, I get an undefined function error.
In my phpinfo() script, I can see that my php installation scans this directory for additional ini files: /etc/php5/fpm/conf.d. Listing the contents of that directory, I can see that my ssh2.ini is there:
ls /etc/php5/fpm/conf.d
mysqli.ini mysql.ini pdo.ini pdo_mysql.ini ssh2.ini
According to phpinfo again, the other four ini files are loaded. SSH2 is not.
I've also tried placing "extension=ssh2.so" directly in my php.ini file - /etc/php5/fpm/php.ini. And yes - I've restarted my nginx server.
Am I missing something else?
Set display_startup_errors = On in you php.ini
Set error_log = '/var/log/php-error.log' in you php.ini
Create error log - touch /var/log/php-error.log
Now, you can restart php5-fpm daemon and lookup in error log any errors with ssh2 module
The answer from Aleksandr was helpful. I was attempting to install a PHP extension for a Plesk build. You need to make the modifications to the Plesk php.ini version that corresponds to the domain (which you can find in the web-based control panel under Tools and Settings). The error log will be located in /var/log/plesk-phpXX-fpm.
Do NOT uncomment the error_log (#2 / #3) as noted above otherwise you won't see the error show up in this location.

How to disable "detect_unicode" setting from php.ini? (trying to install Composer)

I've been trying to install Composer on my machine (OS X 10.6) with no success so far.
As per Composer docs, i executed this in Terminal:
curl -s http://getcomposer.org/installer | php#!/usr/bin/env php
And this is the output:
The detect_unicode setting must be disabled. Add the following to the
end of your php.ini:
detect_unicode = Off
Of course, this is in my php.ini: detect_unicode = Off, located at /etc/php.ini.default
php -info tells me that php.ini file is being loaded from /etc/ (output is: Configuration File (php.ini) Path => /etc)
But, also outputs: detect_unicode => On => On
Why php.ini.default is not loading my settings and how could i disable effecively detect_unicode?
Just add "-d detect_unicode=Off" after the command
curl -s https://getcomposer.org/installer | php -d detect_unicode=Off
Most likely no ini file at all is being loaded, I don't know if /etc/php.ini.default is seen or not by php. Same as I said in Can't set/find detect_unicode to Off - you should run php -i | grep ini and check which file actually is loaded, then edit it. If none is loaded, then make sure you put a php.ini file into the Configuration File Path value, in your case /etc/php.ini it seems.
Under OSX go to /etc.
Open Terminal.
>cd /etc
>nano php.ini.default
Edit the php.ini.default (insert detect_unicode = Off).
Save the file.
Now rename it to php.ini.
>mv /etc/php.ini.default /etc/php.ini
Restart Terminal and then it should work proberly.
If you can't change your /usr/local/bin/php/php.ini file, remember to keep using '-d detect_unicode=Off' for all your php calls like so:
curl -s https://getcomposer.org/installer | php -d detect_unicode=Off
php -d detect_unicode=Off composer.phar install
There are a few solutions online, but the easiest I found was on Stack Overflow. The problem is that the PHP CLI doesn’t load the same php.ini by default, and unlike on most Linux installations there isn’t a seperate php-cli.ini and seemingly /etc/php.ini.default doesn’t load so much. You can pass it as a runtime parameter though:
curl -s getcomposer.org/installer | php -d detect_unicode=Off
source -> http://www.andrew-kirkpatrick.com/2012/10/install-composer-for-php-on-zend-server-mac-os-x/

Location for session files in Apache/PHP

What is the default location of session files on an installation of Apache/PHP on Ubuntu 10.10?
The default session.save_path is set to "" which will evaluate to your system's temp directory. See this comment at https://bugs.php.net/bug.php?id=26757 stating:
The new default for save_path in upcoming releaess (sic) will be the empty string, which causes the temporary directory to be probed.
You can use sys_get_temp_dir to return the directory path used for temporary files
To find the current session save path, you can use
session_save_path() — Get and/or set the current session save path
Refer to this answer to find out what the temp path is when this function returns an empty string.
First check the value of session.save_path using ini_get('session.save_path') or phpinfo(). If that is non-empty, then it will show where the session files are saved. In many scenarios it is empty by default, in which case read on:
On Ubuntu or Debian machines, if session.save_path is not set, then session files are saved in /var/lib/php5.
On RHEL and CentOS systems, if session.save_path is not set, session files will be saved in /var/lib/php/session
I think that if you compile PHP from source, then when session.save_path is not set, session files will be saved in /tmp (I have not tested this myself though).
If unsure of compiled default for session.save_path, look at the pertinent php.ini.
Normally, this will show the commented out default value.
Ubuntu/Debian old/new php.ini locations:
Older php5 with Apache: /etc/php5/apache2/php.ini
Older php5 with NGINX+FPM: /etc/php5/fpm/php.ini
Ubuntu 16+ with Apache: /etc/php/*/apache2/php.ini *
Ubuntu 16+ with NGINX+FPM - /etc/php/*/fpm/php.ini *
* /*/ = the current PHP version(s) installed on system.
To show the PHP version in use under Apache:
$ a2query -m | grep "php" | grep -Eo "[0-9]+\.[0-9]+"
7.3
Since PHP 7.3 is the version running for this example, you would use that for the php.ini:
$ grep "session.save_path" /etc/php/7.3/apache2/php.ini
;session.save_path = "/var/lib/php/sessions"
Or, combined one-liner:
$ APACHEPHPVER=$(a2query -m | grep "php" | grep -Eo "[0-9]+\.[0-9]+") \ && grep ";session.save_path" /etc/php/${APACHEPHPVER}/apache2/php.ini
Result:
;session.save_path = "/var/lib/php/sessions"
Or, use PHP itself to grab the value using the "cli" environment (see NOTE below):
$ php -r 'echo session_save_path() . "\n";'
/var/lib/php/sessions
$
These will also work:
php -i | grep session.save_path
php -r 'echo phpinfo();' | grep session.save_path
NOTE:
The 'cli' (command line) version of php.ini normally has the same default values as the Apache2/FPM versions (at least as far as the session.save_path). You could also use a similar command to echo the web server's current PHP module settings to a webpage and use wget/curl to grab the info. There are many posts regarding phpinfo() use in this regard. But, it is quicker to just use the PHP interface or grep for it in the correct php.ini to show it's default value.
EDIT: Per #aesede comment -> Added php -i. Thanks
Another common default location besides /tmp/ is /var/lib/php5/
I had the same trouble finding out the correct path for sessions on a Mac. All in all, I found out that the CLI PHP has a different temporary directory than the Apache module: Apache used /var/tmp, while CLI used something like /var/folders/kf/hk_dyn7s2z9bh7y_j59cmb3m0000gn/T. But both ways, sys_get_temp_dir() got me the right path when session.save_path is empty. Using PHP 5.5.4.
Non of the above worked for me using the IUS repo for CentOS 7 with PHP 7.2:
php -v
> PHP 7.2.30 (cli) (built: Apr 19 2020 00:32:29) ( NTS )
php -r 'echo session_save_path(), "\n";
>
php -r 'echo sys_get_temp_dir(), "\n";'
> /tmp
However, sessions weren't saved in the /tmp folder, but in the /var/lib/php/mod_php/session/ folder:
ls /var/lib/php/mod_php/session/
> sess_3cebqoq314pcnc2jgqiu840h0k sess_ck5dtaerol28fpctj6nutbn6fn sess_i24lgt2v2l58op5kfmj1k6qb3h sess_nek5q1alop8fkt84gliie91703
> sess_9ff74f4q5ihccnv6com2a8409t sess_dvrt9fmfuolr8bqt9efdpcbj0d sess_igdaksn26hm1s5nfvtjfb53pl7 sess_tgf5b7gkgno8kuvl966l9ce7nn
The only surefire option to find the current session.save_path value is always to check with phpinfo() in exactly the environment where you want to find out the session storage directory.
Reason: there can be all sorts of things that change session.save_path, either by overriding the php.ini value or by setting it at runtime with ini_set('session.save_path','/path/to/folder');. For example, web server management panels like ISPConfig, Plesk etc. often adapt this to give each website its own directory with session files.
I believe its in /tmp/. Check your phpinfo function though, it should say session.save_path in there somewhere.

Categories