We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Require bug with multiple applications on the same server

Hello,

Firstly, sorry if this post in the wrong place. I don't know where to report bugs!

I've found a bug when running multiple micro applications on the same server. The bug appears to be with the "require" PHP method - it's requiring a the wrong file.

I've managed to recreate the bug in a very simple way. I've pushed it to Github and can be found here: https://github.com/jimjam88/phlacon-bug

The repository contains 2 simple applications that are running on the same server. There's both exactly the same but have different responses. I've included the Apache vhost file that I'm using.

Expected outcome:

  • When you navigate to app 1 in a browser (test1.localhost) you should see the message "Hello from App 1"
  • When you navigate to app 2 in a browser (test2.localhost) you should see the message "Hello from App 2"

Actual outcome:

  • When you navigate to app 1 in a browser (test1.localhost) you see "Hello from App 1"
  • When you navigate to app 2 in a browser (test2.localhost) you see "Hello from App 1"

Bizarre!

Ive tracked the problem down to where I am using require_once in each index.php to include the routes.php file in the same directory

require_once __DIR__ . '/routes.php';

The bug also occurs when using require, include or include_once.

When you move the route declarations from routes.php into index.php and remove the "require_once" call then the bug does not occur.

I'm running the latest Phalcon version that is on the master branch. Here's the config from phpinfo:

phalcon

Web framework delivered as a C-extension for PHP
phalcon => enabled
Author => Phalcon Team and contributors
Version => 2.0.6
Build Date => Aug  8 2015 15:51:30
Powered by Zephir => Version 0.7.1b

Directive => Local Value => Master Value
phalcon.db.escape_identifiers => On => On
phalcon.db.force_casting => Off => Off
phalcon.orm.cast_on_hydrate => Off => Off
phalcon.orm.column_renaming => On => On
phalcon.orm.enable_literals => On => On
phalcon.orm.events => On => On
phalcon.orm.exception_on_failed_save => Off => Off
phalcon.orm.ignore_unknown_columns => Off => Off
phalcon.orm.late_state_binding => Off => Off
phalcon.orm.not_null_validations => On => On
phalcon.orm.virtual_foreign_keys => On => On
  • PHP Version: 5.6.10-1+deb.sury.org~trusty+1 (Zend Engine v2.6.0).
  • Apache version: Apache/2.4.10 (Ubuntu)
  • OS: Ubuntu desktop 14.04

Please assist!

Thank you, James



11.6k

try to define your base uri { $url->setBaseUri('/'); in your git exemple} in a more explicit way (ie using 'realpath() ), that could be the source of your problem

Ok so i've found a work around for the bug. It's not pretty but it works. I've added the changed code to the fixed branch.

What i've done is added the base path to the URL compenent...

$di->set('url', function() {
    $url = new Url();
    $url->setBaseUri('/');
    $url->setBasePath(realpath(__DIR__));
    return $url;
}, true);

and then used the base path stored in the URL component to require the routes files:

require_once $di->get('url')->getBasePath() . '/routes.php';

Like i said this is a workaround and I still think that this issue should be looked at by the Phalcon team. The framework should not take PHP functionallity away from us that we all know and love.

Thanks again, James



649
Accepted
answer

This is weiiiiird! I've had a play around some more and this does not seem to be something Phalcon framework is doing... it's PHP. I changed the require statements to use:

require_once dirname(__FILE__) . '/routes.php';

instead of

require_once __DIR__ . '/routes.php';

and it works a treat!

It must be an issue with the way PHP uses the magic constant DIR on Unix filesystems. I've never seen anything like it before - it's very strange.

I'll make this as solved now as it doesn't appear to be an issue with Phalcon.

Thanks, James



11.6k
edited Aug '15

dirname(FILE) and DIR should return the same thing, except when your call DIR from inside your root directory, in this case a trailing slash is added to the DIR constant (it's specified in php docs) so when you use

    require_once __DIR__ . '/routes.php';

from your root folder you get a path like /DIRpath//routes.php