Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Include file into a namespace

I'm working with Magento, but this isn't a Magento specific question.

Let's say that you're working with foo.php with contains the class Foo. In Magento, /local/foo.php will be included if it exists, otherwise /core/foo.php will be included. In both, the class Foo is defined. The problem here is that both files contain the class Foo, therefore the class in /local/foo.php can't extend the class in /core/foo.php. Ultimately this requires all of the code from /core/foo.php to be copied in /local/foo.php minus my customizations.

/core/foo.php - I can't change this file!

<?php
class Foo {
    public function test() {
        echo 'core/foo.php :: Foo :: test';
    }
}
?>

/local/foo_include.php

<?php
namespace mage {
    require '../core/foo.php;
}
?>

/local/foo.php - I can't put a namespace in this file, as I have no control over the file instantiating this class.

<?php
require './foo_include.php';

use mage;
class Foo extends mage\Foo {
    function __construct() {
        var_dump('Un-namespaced Foo!');
    }
}

$foo = new Foo();
$foo->test();

?>

The above doesn't work, saying that mage\Foo doesn't exist. (It does work if the core Foo class is defined inside foo_include instead of being brought in through an include.

Is there any way around this that I'm missing?

like image 243
Tyler V. Avatar asked Mar 19 '14 22:03

Tyler V.


1 Answers

Normally when I see something like this, I feel like the approach isn't right and the problem needs to be examined at a higher view. That said, if this is a hack and you know it, this tweak to your hack will work. But again, I don't recommend either approach.

Change foo_include.php to this:

eval('namespace Mage {?>'.file_get_contents(__DIR__ . '/../core/foo.php').'}');

I'm unsure how Magento works, but with Symfony, the correct solution would be to override the dependency's class via parameters.

http://symfony.com/doc/current/cookbook/bundles/override.html

Is there something similar in Magento? Then you can override the class with your class, and extend the other. This still means they'd need to be in different namespaces, however the framework won't try to go to \Foo since you overrode it. Like such:

# original class for a dependency
dependency.class = \Foo

# overriden with new class
dependency.class = My\Foo

Then in your version of Foo:

class My\Foo extends \Foo {}
like image 97
jmar Avatar answered Sep 28 '22 11:09

jmar