6

In PHP, I wish to import 2 third-party classes, which have the same name. For example:

// in file libs/3rdparty/AppleTree/Apple.php
class Apple extends SomeOtherModel {
  // class details
}

// in file libs/3rdparty/AppleSeed/Apple.php
class Apple extends SomeModel {
  // class details
}

Given that their constructor is the same, e.g.:

$appletree = new Apple();
$appleseed = new Apple();

How can PHP differentiate the two classes? In Java, we can append the class path before the constructor.

Note: I'm using PHP 5 & I can't modify the classes as they are used by other class files.

Esoteric Screen Name
  • 6,082
  • 4
  • 29
  • 38
Raptor
  • 53,206
  • 45
  • 230
  • 366
  • possible duplicate of [How to use same named class in PHP without namespacing?](http://stackoverflow.com/questions/4023360/how-to-use-same-named-class-in-php-without-namespacing) – DCoder May 09 '13 at 04:16
  • not a duplicate, as all answers provided in the above question involve modifying the classes. – Raptor May 09 '13 at 06:01
  • Take that as a demonstration that what you're asking for can't be done. – DCoder May 09 '13 at 06:08

4 Answers4

3

it's not the prettiest and it might not be the most efficient but it DOES work. The concept is this, instead of "including" the files, you read them in as strings, wrap the namespace that you give it around it then evaluate it this will then allow you to call each function with a namespace...

I need to add some mad props to algis for his code in This example i tweaked it to do what you wanted to do.

    function create_namespace($str, $namespace) {
    $php_start = 0;

    $tag = '<?php';
    $endtag = '?>';

    $start_pos = $php_start + strlen($tag);
    $end_pos = strpos($str, $endtag, $start_pos); 

    $php_code = substr($str, $start_pos, $end_pos - $start_pos);
    if (strtolower(substr($php_code, 0, 3)) == 'php')
        $php_code = substr($php_code, 3);

    $part1 = "namespace $namespace ;";

    ob_start();
    eval($part1 . $php_code);
    ob_end_clean();
}

$str1 = file_get_contents('apple1.php');

$str2 = file_get_contents('apple2.php');

create_namespace($str1, "red");
create_namespace($str2, "green");

$apple1=new red\apple();
$apple2=new green\apple();


echo $apple1->color();
echo "<br/>";
echo $apple2->color();

output:

red
green
Community
  • 1
  • 1
bkdude
  • 201
  • 1
  • 6
  • 4
    This is a pretty disgusting solution, but it's the only one that will manage to answer OPs answer, +1. – Daniel Sloof May 09 '13 at 13:09
  • I agree it's not pretty, but it means he can include all his classes and treat them as separate namespaces. I'm curious as to how efficient this is – bkdude May 09 '13 at 13:10
  • i like this crazy approach & it does work ( though a lot more coding is needed ). Thanks for the creativity & madness :) – Raptor May 09 '13 at 16:36
  • The only solution I know. But the problem is that the opcache is not working for evaled file. The solution could be caching the newly created class to php file. – midlan Jun 04 '20 at 21:18
  • thanks!! i've tried `eval(str_replace([''], ['namespace red;', ''], file_get_contents('apple1.php')));` and it works – Vasilii Suricov Nov 22 '22 at 21:45
1

You can use name spaces, but you cannot simply include the file as bkdude specified (Although the idea is right) You will have to add namespace declarion to the top of those files that delare the classed So something like following

#file1
namespace red{

    class Apple
    {
        function me()
        {
            echo __CLASS__;
        }
    }

}

#file2
namespace green {

    class Apple
    {
        function me()
        {
            echo __CLASS__;
        }
    }

}

And include those file wherever you are using them, you will then be able to use as follows.

$apple1 = new red\Apple();
$apple2 = new green\Apple();

$apple1->me();
$apple2->me();
xelber
  • 4,197
  • 3
  • 25
  • 33
  • 1
    but as a requirement, I can't modify the 3rd party files. – Raptor May 09 '13 at 05:59
  • Well then, including probably isn't an option. Even if you write a wrapper at some point the class needs to be included which eventually PHP will complain about the same name. Will probably have to go for a simple XML-RPC to utilize the function. – xelber May 09 '13 at 06:12
  • how to use `XML-RPC` to deal with this case? – Raptor May 09 '13 at 08:06
0

Use namespace. The syntax is the follow:

file1.php
<?php
namespace "mynamespace";



class apple{

}
?>

At this moment, the class apple is only available within the namespace mynamespace. Instantiate the class like this will not work:

<?php
  require_once "file1.php"
  $apple = new apple();

?>

YOu will need use the namespace in order to PHP find the class definition like this:

<?php
  require_once "file1.php"
  use mynamespace;
  $apple = new mynamespace\apple();
?>
Jose Areas
  • 719
  • 3
  • 11
-1

I think for this you need to use namespaces

I'm no expert in namespaces but I would guess something like this.

<?php
namespace red {

include (apple1.php);
}

namespace green {

include (apple2.php)
}
?>

then call then like $nice= new red/apple() and $rotten= new green/apple()

Community
  • 1
  • 1
bkdude
  • 201
  • 1
  • 6
  • Although the idea is right, including the file wont solve the issue as PHP treat every include as a separate entity. – xelber May 09 '13 at 05:27
  • `Fatal error: Namespace declaration statement has to be the very first statement in the script`. This method is not working. (why 2 upvote I doubt?!) – Raptor May 09 '13 at 08:05
  • The syntax for namespace in php is not correct in this example. Check my answer out. – Jose Areas May 09 '13 at 15:08