PHP Static analysis to detect breaking changes in advance of upgrade - php

We have a large codebase and it's currently running in production on PHP 7.4. Now we're getting ready to upgrade to PHP 8.1 and so we've been asked to make sure the code is going to work when we upgrade.
We have phpcs of course, and this will detect things that have been completely removed by PHP 8.1 (or PHP8.0) to make sure that the code runs without fatal errors, but there are a bunch of things listed in the migration docs from php7.4 to php8.0 where behaviour will change and I don't see any warnings that if I upgrade to 8.0 then my code will behave differently. Or said another way, I'd like to be pointed to the exact places that I need to modify my code if I want the behaviour not to change after the upgrade.
To illustrate, here's a file test.php:
<?php
if(0 == "foo") {
echo "this was true in php 7.4, you must be running 7.4 or lower\n";
} else {
echo "this is false in php 8.0, you must be running 8.0 or higher\n";
}
Because of a change between PHP 7.4 and PHP 8.0 the behaviour of this code will differ depending on which version of php is running it, but I haven't found how phpcs can be made to warn me about this while I'm still on 7.4 and preparing to go to 8.0. I've tried:
composer global require squizlabs/php_codesniffer:^3 phpcompatibility/php-compatibility:^9
$(composer config -g home)/vendor/bin/phpcs \
--standard=$(composer config -g home)/vendor/phpcompatibility/php-compatibility \
--runtime-set testVersion 8.1 test.php
But this doesn't detect the if(0 == "foo") { which might break everything post upgrade...
There seem to be quite a few tools that check for backward compatibility but I guess I'm looking for checking forward compatibility.
Is this doable with phpcs? Or is there another static analysis tool that will help me prepare for an upgrade by catching these breaking changes? If not, what other ways of preparing for an upgrade do you recommend, considering a very large codebase?

Related

Can't Run PHP Imagick from Command Line?

I realize that Imagick has it's own command line executables, but why whenever I try to run an Imagick command written in PHP it breaks my script and exits without warning?
Take something simple:
<?php
$imagepath = realpath('1.gif');
var_dump('111');
$image = new Imagick($imagepath);
var_dump('222');
var_dump($image);
Running php -f imagick.php on my command line interface just simply outputs string(3) "111" and then immediately exits once it hits any Imagick function.
Imagick is properly installed on my machine, and if I do a php -m it shows Imagick as an installed module.
Is there anyway to get it working in command line scripts (aside from using exec())?
I was slightly worried that it wouldn't work on cron jobs, but I just did a quick test and it seems to be working within that (least on VPS).
Am trying from Windows x64 WAMP server PHP v7.1.16.
Note: To clarify, this is just a command line issue. Imagick is installed correctly, no issue with syntax, I've been using it for months in the browser with no issues.
Even command line attempts.. php -d display_errors imagick.php, same, dies upon impact of IM with no notice php -n -l -d display_errors -d display_startup_errors imagick.php brings back 'No Syntax Errors'. It's peculiar, nothing should simply kill the script (although it does try to load for a second before it essentially breaks out of the script no matter where it's at) without any notice.. then again since there's no issue running it in the browser over and over, so I don't think there is any errors (especially sampling my above one liner Imagick initalization).. it's just a CLI thing that I do not understand.
This was a local issue, apparently.
I recently reinstalled Windows and subsequently reinstalled Imagick and PHP.
Anyone else having similar issues I recommend reinstalling Imagick (it's a big pain to install -- recommend using these references for installing on a Windows 10 machine:
Installing Imagick for PHP 7 on Windows 10
Proper Way to CLI PHP within WAMP (WAMP64), while switching between Multiple PHP Versions on Windows 10
Also I've yet to try this personally, but by the looks of it, seems a better method for imagick integration with PHP: ImageMagickPHP (Imagick PHP Class that utilizes command line exec as opposed to the PHP version).

php from command line empty

I have updated windows today and now when I use the command line and type PHP nothing returns. tried various PHP commands, nothing, not even an error or response. blank.
I had the correct path in the environment variables. Tried to change to another PHP version and even tried removing the path from environment variables but still returns empty!
It doesn't even say that "PHP" is not recognized although I removed the environment variable!!
I have no clue how to solve this.
If you are not passing extra parameters when you call it from command line, that´s how it supposed to work.
Try running:
php --help (to see all options from command line)
Also, to make sure it is running try to do this:
php -v (to check version)
php -F filename.php
The last one should run your php file.
I had the same challenge.
Here's a solution:
Use a standard terminal window (instead of Powershell).
Try php -v again.
IF you get an error mentioning VCRUNTIME140.dll
THEN you need to install run-time components that are required to run C++ applications built using Visual Studio 2015 here: https://www.microsoft.com/en-us/download/details.aspx?id=48145

How to debug PHP CLI scripts from the CLI

Does anybody know how to debug CLI PHP scripts from the CLI?!? I don't want to debug a PHP web page - I don't have a PHP web page. I don't want to debug a remote script either - I'm running/debugging right here on this system. I don't want to (at this time) try to get some IDE (Eclipse, PhpStorm or whatever) to debug a CLI PHP rather I just want to debug some PHP CLI script at the Linux command line itself. In Perl this would be simply perl -d <script.pl> <options>. Debugging a script, to me, is not figuring out compile errors or other simple things. To me it's setting break points, running code, examine the contents of variables and being able to arbitrarily execute or eval ('<php code>') at the debugger.
Sure later I'd like to configure this into my IDE of choice (at this time this is Eclipse) but I have not managed to get that working. Debugging from the CLI a PHP CLI script would be a good start for me.
Thanks.
I don't know why I'm limited to a character count when posting a comment. Perhaps I can add more text here.
Here's what I have tried in order to use xdebug and/or Zend debugger with Eclipse:
Base Eclipse version Mars.1 Release 4.5.
Eclipse PDT UI Plugin version 3.7.0.2015112
Tried installing xdebug using pecl install xdebug. Says I need to add "zend_extension=xdebug.so" to php.ini. Really? Which php.ini? I have several:
Andromeda:sudo find / -xdev -name php.ini
/etc/php5/cli/php.ini
/etc/php5/apache2/php.in
/opt/eclipse/plugins/org.zend.php.debug.debugger.linux.x86_64_5.3.18.v20110322/resources/php53/php.ini
/opt/eclipse/plugins/org.zend.php.debug.debugger.linux.x86_64_5.3.18.v20110322/resources/php5/php.ini
/opt/eclipse/plugins/com.zend.php.debug.debugger.php56.linux.x86_64_13.0.1.v20151112-2045/resources/php56/php.ini
Andromeda:
I put the zend_extension thing in both /etc/php5/cli/php.ini and /etc/php5/apache2/php.ini. Made a phpinfo.php page and I see Xdebug in there (yea!). Configure a Debug Configuration in Eclipse to use xdebug and try to debug:
Launching renameUser has encountered a problem. An internal error occurred during "Launching renameUser" java.lang.NullPointerException.
Oh goodie...
I had also installed the Zend Debugger and added the following to those same two php.ini files:
zend_extension=/usr/lib/php5/20121212/ZendDebugger.so
zend_debugger.allow_hosts=127.0.0.1/32, 192.168.0.0/16
zend_debugger.expose_remotely=always
Changed debug configuration to use Zend Debugger and attempted to debug. Received:
Error launching 'renameUser' The debug session could not be started. Please make sure that the debugger is properly configured as a php.ini directive.
Restarted Eclipse and now the debugger attempts to run but simply terminates with a 255 exit value attempting to run /opt/eclipse/plugins/org.zend.php.debug.debugger.linux.x86_64_5.3.18.v20110322/resources/php5/php-cgi. Why it's runnign php-cgi is beyond me. I said this was a CLI not a CGI. In any event I get the following when trying to run this from the command line:
Andromeda:/opt/eclipse/plugins/org.zend.php.debug.debugger.linux.x86_64_5.3.18.v20110322/resources/php5/php-cgi
/opt/eclipse/plugins/org.zend.php.debug.debugger.linux.x86_64_5.3.18.v20110322/resources/php5/php-cgi: error while loading shared libraries: libiconv.so.2: cannot open shared object file: No such file or directory
Found a libiconv.so.2 in /opt/eclipse/plugins/org.zend.php.debug.debugger.linux.x86_64_5.3.18.v20110322/resources/lib and set LD_LIBRARY_PATH to include that but this just fails to launch the debugger at all stating to make sure that the debugger is properly configured as a php.ini directive... UGH!
Other odd stuff:
When Eclipse starts up it fails to open my RSE based project thus displaying edit buffers from the last run as empty
Eclipse will no longer exit! Select File: Exit. Nothing happens. Click on the X in the title bar - nothing happens. Now I have to kill it to close it!
When debugging on the command line you need to tell PHP you want to debug also
http://xdebug.org/docs/remote
says
export XDEBUG_CONFIG="idekey=session_name"
php myscript.php
assuming xdebug is enabled (it doesnt matter which .ini file its in, but there is a standard place per OS for this, usually in a conf.d folder called xdebug.ini which is auto included)
This allows you to debug a cmdline script.
Personally I use Vim with Vdebug extention (xdebug for vim) to debug and nothing other than a command line is needed
What worked for me was using dephpugger. I found the steps to get CLI debugging working here:
https://hackernoon.com/how-debug-php-applications-with-dephpugger-98cc234d917c
I had previously installed xdebug and tried out exussum's answer.
The steps I followed are included here for completeness.
Install dephpugger:
composer global require “tacnoman/dephpugger”:”dev-master”
Put dephpugger on the path:
export PATH=$PATH:$HOME/.composer/vendor/bin
make sure to include in the php file at the breakpoint:
xdebug_break();
open up 2 terminal instances. In one run:
dephpugger debug
In the other run
dephpugger cli /path/file.php
replacing /path/file.php with the path to your file. if you need command line arguments to the php script put the path and arguments in quotes. It still seems a little hacky. I think the real trick is to write in a language that has a better debugger built in.
exussums answer works for me.
In addition I have the following in /etc/php/7.0/cli/conf.d/20-xdebug.ini
zend_extension=xdebug.so
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000
xdebug.remote_handler=dbgp
xdebug.remote_enable=true
#xdebug.remote_enable=false
And I had to do this: https://github.com/vim-vdebug/vdebug/issues/363
Being able to set break points in a PHP script requires some kind of debugger extension being loaded, either XDebug or Zend Debugger.
And then you need some kind of interface to this debugger to make your wishes about break points known. I am unfamiliar with the Perl debugging, but I haven't heard about any PHP CLI based debugging - it is always taking place in an IDE that is able to handle the debugging protocol of one of the extensions.
Of course there is the good old var_dump();die('hi'); debugging, but this does not include continuing code execution after the script ended. ;)

PHP from source - Questions about Extension-Folder and Interaction with existing repo-version

As a Linux beginner I'm currently a bit confused building my own PHP from source.
I have a Ubuntu with a LAMP-Stack where all packages comes from a Repository.
(PHP as FastCGI)
Now I'm trying to set up a second PHP-Version and actually it works well but I have a few questions.
First of all some specs:
Ubuntu 10.04 (I need this older Version)
PHP 5.3.2-1ubuntu4.2.5 (Repo)
For my own PHP-Version I use the following "./configure" parameters (Reduced to the essential):
--prefix=/opt/php5310
--with-config-file-path=/opt/php5310/etc
--with-config-file-scan-dir=/opt/php5310/conf.d
--with-libdir=lib64
--with-mysql=/usr/bin/mysql
...
First of all executing "sudo make test" show up a few failed tests (about 10-14). Unfortunately I can't find any information what I have to do or what excactly goes wrong but "sudo make install" works nevertheless.
Is it normal that not all tests passed?
Then I noticed (phpinfo) the "imagick" extension was not loaded.
Looking at the "extension_dir" shows why.
On the Repo-Version:
extension_dir = /usr/lib/php5/20090626
On my own Version:
extension_dir = /opt/php5310/lib/php/extensions/no-debug-non-zts-20090626
(This folder doesn't even exist)
When I put this inside the php.ini:
extension_dir = /usr/lib/php5/20090626
It's working but is it the right way or just a creepy workaround?
And what about "--with-libdir=lib64" doesn't it belong to "extension_dir"?
On my System /usr/lib64 is a symlink to /usr/lib.
And last but not least my Repo-Version has a folder "/etc/php5/cgi/conf.d" with many ".ini" files e.g. "curl.ini", "gd.ini" and so on.
My Solution was:
"--with-config-file-scan-dir=/opt/php5310/conf.d
And then create the "conf.d" Folder and copy everthing from "/etc/php5/cgi/conf.d" to "/opt/php5310/conf.d" to be not dependent on the PHP Repo-Version.
Would this be a correct solution for multiple PHP-Versions or should it be a symlink or
"--with-config-file-scan-dir=/etc/php5/cgi/conf.d
Thank you for your help
Failing tests generally means failing functionality. Of course, for something as large as PHP you may never touch that functionality. It may be that your best bet here is to search for the names of the tests which failed to see if anyone has had the same issue (and how to fix it or disable the functionality), and to find the source of the tests in PHP and understand why they failed.

zf tool & PHPunit not recognised in include_path

I've be struggling with this for a while.
When using the zf tool included in the Zend Framework 1.11 to both create projects and actions and so on, I always get the notice that PHPUnit was not found in the include path and hence the test have not automatically been created. I know that this is only a notice and not an error however I would like it to work.
I am using OS X 10.7 and MAMP, my include path in MAMP is as follows:
include_path = ".:/Applications/MAMP/bin/php/php5.3.6/lib/php:/Applications/MAMP/bin/php/php5.3.6/lib/php/PHPUnit"
The only hint of the problem I have found so far on the internet is that the zf tool is using the natively installed php and include path and hence not noticing the PHPUnit.
I suppose that I could find the php.ini file and add the PHPUnit to it's include path but it feels a little bit of a hack.
Is there away to "prioritise" php installs?
Thank you for you help.
Al
I have finally found the answer at http://wiki.dreamhost.com/Zend_framework
Basically follow Step 5.
Replace
# find php: pear first, command -v second, straight up php lastly
if test "#php_bin#" != '#'php_bin'#'; then
PHP_BIN="#php_bin#"
elif command -v php 1>/dev/null 2>/dev/null; then
PHP_BIN=`command -v php`
else
PHP_BIN=php
fi
with
PHP_BIN=/Applications/MAMP/bin/php/php5.3.6/bin/php
Thank for your help anyway.

Categories