Search code examples
phpangularjsphpstormxdebug

PHP warnings that should not be occurring with Xdebug, AngularJS, and PhpStorm


This is a head-scratcher. I inherited an AngularJS project that's backed by PHP on the server side. I was tasked with writing a little data caching function, which is embarrassingly simple. Unfortunately, that's when things broke on the front end. Before I continue further, I'll show my PHP code so I can point to things. File structure and other assorted names changed due to NDA, and code not related to the problem removed:

define('ROOT', dirname(__FILE__));
require('config/config.php');
require('includes/includes.php');

// caching

function cacheCategories()
{
    $dirPath = ROOT . '/cache/categories';
    $cacheFileName = '/categories.json';
    $cacheFilePath = $dirPath . $cacheFileName;
    $cacheTime = 86400;

    if (file_exists($cacheFilePath) && (time() - $cacheTime) < filemtime($cacheFilePath)) { // cache file exists and is fresh
        $cachedJSON = readfile($cacheFilePath);

        if ($cachedJSON === false) {
            throw new Exception('Could not read from cache file');
        }
    } else {
        include_once('/site/load.php');
        $categories = load_categories_tree();
        $cachedJSON = json_encode($categories);

        if (!is_dir($dirPath)) {
            mkdir($dirPath);
        }

        $fp = fopen($cacheFilePath, 'w');

        if ($fp === false) {
            throw new Exception('Could not open cache file');
        }

        if (flock($fp, LOCK_EX)) {
            $writeResult = fwrite($fp, $cachedJSON);

            if ($writeResult === false) {
                throw new Exception('Could not write to cache');
            }

            flock($fp, LOCK_UN);
            fclose($fp);
        }
    }

    return $cachedJSON;
}

global $page;
$page = new Page('');
$page->setDefaultLanguage('en');

echo cacheCategories();

As you can see, it's pretty simple. If a cache file exists, and is fresh, the data is simply loaded from that. If not, a new cache file is created. The cache directory is created if necessary.

My problem is that when AngularJS attempts to grab the data from this PHP file, xdebug generates a warning about mkdir, and I also get a generic Exception:

<br />
<font size='1'><table class='xdebug-error xe-warning' dir='ltr' border='1' cellspacing='0' cellpadding='1'>
<tr><th align='left' bgcolor='#f57900' colspan="5"><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>( ! )</span> Warning: mkdir(): No such file or directory in /home/mp/www/tiles/api_categories.php on line <i>39</i></th></tr>
<tr><th align='left' bgcolor='#e9b96e' colspan='5'>Call Stack</th></tr>
<tr><th align='center' bgcolor='#eeeeec'>#</th><th align='left' bgcolor='#eeeeec'>Time</th><th align='left' bgcolor='#eeeeec'>Memory</th><th align='left' bgcolor='#eeeeec'>Function</th><th align='left' bgcolor='#eeeeec'>Location</th></tr>
<tr><td bgcolor='#eeeeec' align='center'>1</td><td bgcolor='#eeeeec' align='center'>0.0001</td><td bgcolor='#eeeeec' align='right'>241456</td><td bgcolor='#eeeeec'>{main}(  )</td><td title='/home/mp/www/tiles/api_categories.php' bgcolor='#eeeeec'>../api_categories.php<b>:</b>0</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>2</td><td bgcolor='#eeeeec' align='center'>0.0015</td><td bgcolor='#eeeeec' align='right'>715400</td><td bgcolor='#eeeeec'>cacheCategories(  )</td><td title='/home/mp/www/tiles/api_categories.php' bgcolor='#eeeeec'>../api_categories.php<b>:</b>67</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>3</td><td bgcolor='#eeeeec' align='center'>3.8601</td><td bgcolor='#eeeeec' align='right'>54575184</td><td bgcolor='#eeeeec'><a href='http://www.php.net/function.mkdir' target='_new'>mkdir</a>
(  )</td><td title='/home/mp/www/tiles/api_categories.php' bgcolor='#eeeeec'>../api_categories.php<b>:</b>39</td></tr>
</table></font>

<pre>exception 'Exception' with message 'Could not open cache file' in /home/mp/www/tiles/api_categories.php:45
Stack trace:
#0 /home/mp/www/tiles/api_categories.php(67): cacheCategories()
#1 {main}</pre>

The weird thing is, when I access the PHP file directly, no warnings, errors, or exceptions pop up. The cache file is created properly upon my first visit, and read from properly in subsequent visits.

This issue started when I setup zero configuration PHP debugging in PhpStorm. Before that, the project was working perfectly. It's almost as though Angular is grabbing a cached version of an old warning or something, because, again, when I access the PHP file directly, it works as it should.

Any ideas? I'm new to Angular, so is there a way I can purge whatever cache it may have?


Solution

  • Figured it out. Like someone said in an apparently now deleted comment to my question, is_dir() cached the result of a failure state from before. Invoking clearstatcache() cleared it right up.