PHP troubleshooting: edit the phpcs config file to fix missing or moved coding standards

If phpcs isn’t working properly and running phpcs -i (to get a list of installed coding standards) gives you an error message like this:

PHP Fatal error: Uncaught UnexpectedValueException: DirectoryIterator::__construct(/path/to/a/set/of/phpcs/coding/standards/that/no/longer/exists): failed to open dir: No such file or directory in /usr/local/Cellar/php-code-sniffer/2.8.1/CodeSniffer.php:2250

The quickest way to fix it is to search for the CodeSniffer.conf file (MacOS users, try /usr/local/etc/PHP_CodeSniffer/CodeSniffer.conf) and then edit the installed_paths key to remove or rename the problem directory.

Your output should then look something like this:

$ phpcs -i
The installed coding standards are MySource, PEAR, PHPCS, PSR1, PSR2, Squiz, Zend, Drupal, DrupalPractice, WordPress, WordPress-Core, WordPress-Docs, WordPress-Extra and WordPress-VIP

Troubleshooting: Where has the PhpStorm PHP 7 Compatibility Inspection gone?

If you’ve read this guide to checking PHP code for PHP 7 compatibility / used the inspection in the past, you may notice that it’s apparently disappeared – you’re supposed to be able to choose Run Inspection by Name… and choose PHP 7 Compatibility from the list.

This is because it’s been merged with the Language Level inspection.

So:

  • Preferences > Languages and Frameworks > PHP
  • set desired PHP Language Level under Development environment
  • Run inspection by name…
  • choose Language Level

Thanks to Jetbrains Support for helping me with that..

(Tested with PhpStorm 2017.1 EAP)

Troubleshooting Composer timeouts (IPv6 issue)

If composer hangs and you eventually see this error:

The "https://getcomposer.org/versions" file could not be downloaded: failed to open stream: Operation timed out

it could be a problem with IPv6 (for example if you’ve lost your IPv6 address for some reason.)

On MacOS you can turn IPv6 on and off via the command line.  This:

networksetup -listallnetworkservices

…will give you a list of network interfaces (e.g. Ethernet, Wi-Fi, any VPNs)

networksetup -getinfo Wi-Fi

…will list all it’s settings; IP address, MAC and IPv6 status.

networksetup -setv6off Wi-Fi

…will turn IPv6 off. (To turn it back on, you’ll typically want -setv6automatic, though there’s also an option to set it manually.)

In my experience turning it off fixed the problem immediately, and composer worked straight away.

Obviously it’s preferable to fix your IPv6 and turn it back on, but this may be inconvenient if you have to reboot router etc. or beyond your control if there’s a problem with your ISP.

Useful page to test your IPv6 connection: http://ipv6test.google.com/

See also this GitHub issue

Tested with MacOS El Capitan 10.11.5

Troubleshooting Laravel ‘Class log does not exist’ error

This is a common problem – the error is in Illuminate/Container/Container.php (line 736 or 741).

Forum thread

Common reason: spaces in environment variable values in .env file

Two other fixes that have worked for me:

  • after an apt-get upgrade on Homestead, installing the php7.0-mbstring package fixed it (Laravel needs four PHP extensions: OpenSSL, PDO, Mbstring and Tokenizer)
  • on another installation, changing syntax from:
    $app->environment('production')

    to:

    'production' === env('APP_ENV')

    in a ternary operator in config/app.php was the solution.

 

Troubleshooting remote debugging with Xdebug in PhpStorm

Updated Fri 7 Dec 2018.

Running Xdebug remotely is very useful – you can add breakpoints, inspect and modify the state of all variables/objects and type PHP code into a live console.  No need to manual add var_dump() statements etc.
It should save you a lot of time.

Unfortunately, while the setup should be straightforward, it’s easy to lose the programming time you save spending ages tweaking your Xdebug and PhpStorm configuration to get it to work in the first place. (In fact, I don’t think it’s worked correctly first time for me once.)

Also, you’ve probably got multiple projects, maybe running on different VMs, or using Docker (scroll down for special instructions for Docker on the Mac).

Drupal users:

There’s an element of “it just works” for Xdebug in the server/PhpStorm configuration when using Acquia Dev Desktop or Drupal VM.

Acquia Dev Desktop:

To enable/disable Xdebug:

edit /Applications/DevDesktop/php7_1/bin/php.ini
Uncomment the zend xdebug extension and turn on remote_enable

zend_extension=xdebug.so
xdebug.remote_enable = 1

Restart Apache – via one of:

  • the DevDesktop UI
  • the UI but with keyboard shortcuts, cmd-2 (stop) then cmd-1 (start)
  • CLI: /Applications/DevDesktop/apache/bin/apachectl -k restart

Drupal VM:

To turn on xdebug, make sure you’ve got:

php_xdebug_default_enable: 1

and:

installed_extras:
[...]
- xdebug

Then run vagrant provision to build/rebuild (this won’t affect your site). Leave PhpStorm set to port 9000.

Everyone else (non Drupal):

On other installations, here’s my growing checklist when I try to use Xdebug and nothing happens:

(The following is based on Xdebug 2.4.0RC4 and PhpStorm 2016.2.1)

Step 1: you should identify whether it’s a complete lack of communication between Xdebug and the IDE, or if PhpStorm is receiving the data the data but is setup wrong.

Close and restart PhpStorm.  Make sure PhpStorm is listening for PHP Debug Connections (bottom of Run menu, or green telephone icon top right), then reload your app in the browser.

What you’re looking for is either:

a) an ‘Incoming connection’ dialog the very first time you open a webpage of your app.
or
b) ‘Debug session was finished without being paused” in the Event Log.

Either of these confirms Xdebug is talking to PhpStorm and you can need not worry about your php.ini entries, the possibility you’re using the wrong port or that you forgot to trigger the bookmarklet – goto section B.

If nothing happened at all, go to section A.

A. Communication failure

  • Ensure the bookmarklet (recommended) or browser addon you’re using to start/stop debugging is activated.  You can use developer tools to verify the cookie is being sent.
  • Is Xdebug installed? (check phpinfo() output)
  • Does the Xdebug section of phpinfo() have this warning: “XDEBUG NOT LOADED AS ZEND EXTENSION”?  You’re meant to use zend_extension=xdebug.so, not extension=xdebug.so – go to the wizard, paste in your phpinfo() contents and it’ll generate a fully customised set of commands to run (< 2-3 mins) to download the xdebug extension and compile it for your system. (I’ve had this problem break one site – further info).
  • Make sure the bookmarklet’s cookie is correct, it should use PHPSTORM for the IDE key.    does the browser IDE key match xdebug.idekey in your php.ini file? (Verify correct config file is being loaded – have you confused configs for multiple versions or CLI/fpm – and correct value read from it by creating a test page with phpinfo() output.)  Correction: specifying xdebug.idekey in php.ini is unnecessary.  Note if you view the phpinfo() output, at the top of the Xdebug section there’s are two rows, listing the version and the IDE key. If xdebug.idekey is unset, XDebug will fall back to the value of $_SERVER[‘USER’], e.g. www-data, but regardless, as soon you activate your bookmarklet to start a debug session, the $_COOKIE[‘XDEBUG_SESSION’] is set to ‘PHPSTORM’ and that’s what’s passed through. (To test, start and stop a session whilst refreshing your phpinfo() page and watch the IDE key change.)
  • php.ini – ensure xdebug.remote_enable is set to 1 (then restart php-fpm, refresh page and keep an eye out for ‘Debug session was finished without being paused’ in the Event Log)
  • php.ini – you may well need xdebug.remote_connect_back = 1 too (again, restart php-fpm) – I’ve had multiple dev sites that require it – XDebug may be ignoring the connection from the debug client because it doesn’t match xdebug.remote_host, turning on remote_connect_back makes it ignore this and accept a connection from anywhere – make sure your dev machine is behind a firewall.
  • Check the ports match – this can get reset by mistake.  You may also need to use 9001 rather than the default 9000 if the latter is also being used by php-fpm on your server.  Also, open the Event Log and look for a message like “Can’t start listening for connections from ‘xdebug’: Port 9000 is busy”. Ports must be set correctly in two places – xdebug.remote_port and PhpStorm’s preferences (Languages & Frameworks > PHP > Debug > Xdebug)
  • You can verify both ends of this, the phpinfo() output will confirm what port Xdebug will send on.  You can verify PhpStorm is actually listening on the correct port with the lsof command (this example from macOS):
    wt$  sudo lsof -i :9001
    Password:
    COMMAND    PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
    phpstorm 80592   wt  330u  IPv4 0xaad56de5076720c3      0t0  TCP *:etlservicemgr (LISTEN)

    If PhpStorm is not listening this will be blank.

B. PhpStorm settings

  • By default Xdebug won’t do anything if no breakpoints were found. Check the Event Log pane – there will be a warning message, e.g. “Debug session was finished without being paused”. Is there one?
  • You may have configured Remote debugging to skip certain paths. In Preferences, check Languages & Frameworks > PHP > Debug > Skipped Paths (there’s no warning in Event Log if a script is skipped.)  Are you trying to verify an AJAX request, when, for example in WordPress, you have previously blocked admin-ajax.php to avoid spawning a new debug session every time autosave is triggered?
  • If PhpStorm is always stopping on the first line of the script but you don’t want it to, note that this option is specified in two separate places – one at the bottom of the run menu (“Break at first line in PHP scripts”) and also in Preferences (Languages & Frameworks > PHP > Debug > External connections)
  • Path mappings can get confusing. The left section is the project files that PhpStorm is looking at.  The column on the right needs to the path on the server – so you have a Vagrant box running on a Mac host, don’t use /Users/<name>/…, use /var/www/…, /usr/share/ etc.  Double check PhpStorm has saved what you’ve entered correctly.
  • If nothing’s happening, make sure all your previous debug sessions have finished. Press the stop button in the debug panel (cmd-F2 on Mac) and try reloading the page again. Also note also the Max. simultaneous connections setting.
  • Have you lost the Debug window, e.g. you minimised it and can’t find it again? Press cmd-5 or hover over the square in the far bottom-left of the screen.
  • Struggling to find the Path mappings dialog? Go to Preferences > Languages & Frameworks > PHP > Servers
  • Common mapping errors: Typically failing to map the document root (e.g. say in WordPress, you’ve mapped wp-admin and nothing else.)

Skipping the Incoming Connection dialog

Note: you might want to set the PHP_IDE_CONFIG environment variable on your server. This tells PhpStorm which path mapping configuration it should use so it doesn’t prompt you.  It needs to be written like this:

serverName=my-server.dev

where my-server.dev must match the name configured in Languages & Frameworks > PHP > Servers – as shown below:

PhpStorm - configuring the server name

PhpStorm’s Debug diagnostic tool

Go to: Run > Web Server Debug Validation (instructions here)

PhpStorm, Xdebug, Docker & Mac

Your Docker containers will have an IP address beginning 172.xxx.xxx.xxx (each container gets it’s own – check what it is)  You might assume that’d be enough to avoid conflicts with your real IP address or 127.0.0.1 when specifying xdebug.remote_host.

Note: on macOS, you need to create a symlink to your IP otherwise PhpStorm won’t be able to hear Xdebug.

  1. Create the alias:
    sudo ifconfig lo0 alias 10.254.254.254
  2. Put this new address (10.254.254.254) in:
    – your /etc/hosts file (an entry for your project’s hostname)
    – xdebug.remote_host (whether that’s in php.ini or an environment variable in docker-composer.yml)
    – PhpStorm in Preferences > Languages & Frameworks > PHP > Debug > DBGp Proxy > host

Restart everything and things should start working.

Related info:

PHP mistakes to avoid: objects and references

This is a fairly crucial bit of object-oriented PHP, but I only found out about it today after x years, so it’s bound to trip someone else up.

Essentially, if you want to copy some values from an object, doing this is a very bad idea:

$a = new A;
$b = $a;

…because it’s not like copying a variable (passing it by value) where $a and $b are independent, $b is just a pointer to $a. So this:

unset($b->foo);

…will remove foo from $a as well.

Wiser programmers than me may well be saying, “Why do you need to copy an object anyway?”, and indeed I can’t remember doing so before.

I needed it’s properties, so I could write a record of an API call to a logfile (but minus sensitive info like the API keys).  These were indeed removed from the log, unfortunately all the REST calls stopped working and it took a while to realise why.  get_object_vars (which chucks the properties in an array and leaves the original object intact) was what I should have used.

Note objects are passed as pointers, not as references, as explained in great detail here (read the comments.)

How to upgrade Laravel Homestead to PHP7

I wrote this StackOverflow answer, explaining how you can safely backup  your work, destroy the old PHP 5.6 Vagrant box and download a brand new one that comes with PHP 7 as standard.

In my opinion this will be easier and cleaner for most people than trying to perform an in-place upgrade (the exception is where you’ve extensively customised PHP, MySQL or Nginx, in which case you need to backup the appropriate config files too.)

There are also some notes on the format of Homestead.yaml when you have more than one site, as the documentation on shared folders isn’t terribly clear.

PhpStorm troubleshooting – ideaVim stops working

IdeaVim is a popular plugin that adds vim shortcuts (e.g. hjkl navigation) to PhpStorm and similar products.

A rare bug Mac users may replicate one day: it’s possible to accidentally disable IdeaVim by pressing cmd-alt-V – the same shortcut as moving files in Finder.  PhpStorm does need to have focus; in my case I was typing the standard copy/paste/move shortcuts to transfer some files in the Project window.

You can see/toggle the Vim status with Tools > Vim Emulator (which won’t show up as a search result if you use shift-cmd-A and type ‘ideavim’).  It’s a handy shortcut to be aware of – temporarily turning Vim off may make it easier to complete certain refactoring tasks where you’re entering a new variable name.

IdeaVim’s settings are in vim_settings.xml in the WebIde100 folder (where the 100 at the end indicates version 10.0.*), in the event of a problem you can inspect or trash that file.