Last active
August 29, 2015 14:14
-
-
Save pniederlag/c61c2bd75a02c78ab71d to your computer and use it in GitHub Desktop.
makeInstance adressing issue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Demonstrate the usage of makeInstance and/or php namespaces adressing background |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace test { | |
class foo { | |
} | |
// fixed | |
$testFoo = new foo(); | |
//$anotherFoo = test/foo(); // fatal | |
$testYetAnotherFoo = new \test\foo(); | |
// dynamic | |
// $foo = 'foo'; // fatal | |
$fooFullyQualifiedName = '\\test\\foo'; | |
$fooQualifiedName = 'test\\foo'; | |
$testFooFullyQualified = new $fooFullyQualifiedName; | |
var_dump(get_class($testFooFullyQualified)); | |
$testFooQualified = new $fooQualifiedName; | |
var_dump(get_class($testFooQualified)); | |
} | |
namespace { | |
// fixed | |
// $testFoo = new foo(); // fatal | |
$anotherFoo = new test\foo(); | |
$testYetAnotherFoo = new \test\foo(); | |
echo "" . PHP_EOL; | |
// dynamic | |
$fooFullyQualifiedName = '\\test\\foo'; | |
$fooQualifiedName = 'test\\foo'; | |
$testFooFullyQualified = new $fooFullyQualifiedName; | |
var_dump(get_class($testFooFullyQualified)); | |
$testFooQualified = new $fooQualifiedName; | |
var_dump(get_class($testFooQualified)); | |
echo "" . PHP_EOL; | |
echo "Lessons learned:" . PHP_EOL; | |
echo "In *global* scope you can use 1) full qualified name *or* 2) qualified names" . PHP_EOL; | |
echo "php internally always represents the classname only *qualified*" . PHP_EOL; | |
echo "which is fine because from php perspective this is *global* namespace scope" . PHP_EOL; | |
echo "" . PHP_EOL; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* in plain PHP | |
*/ | |
// qualified relative (subnamespace) class instantiation | |
$fileUtility = new File\BasicFileUtility(); | |
// fully qualified (absolute) | |
$fileUtility = new \TYPO3\CMS\Core\Utility\File\BasicFileUtility(); | |
/* | |
* TYPO3 makeInstance or any other plain dynamic language context (variables as class names etc. pp') | |
*/ | |
$fileUtility = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Utility\\File\\BasicFileUtility'); | |
// Thx to @helhum for clearification/explanation | |
// we are using a dynamic language feature (classname as variable), thus it will be always interpreted in *global* namespace. | |
// So both fully qualified(leading slash) as well as qualified names do work from php perspective | |
// As internally the class name is stored qualified (without leading slash) it is easier to force to supply names qualified only. |
First of all many thx for your comment and very nice and exact explanations.
DEV without TYPO3 Background most likely would think this is "relative"
This has exactly NOTHING to do with TYPO3 background! Devs need to learn and understand that class names passed as strings are in global scope in PHP thus always fully qualified
full ACK,
So I blame PHP for
- allowing both fully qalified(leading slash) as well as qualified names on global scope
- representing class names qualified(sic!) internally, instead of fully qualified
Still to me the fully qualified name is more intuitive (while it might be redundant). But as now I got the whole picture of all the implications of fully qualified vs. qualified I got your point.
btw, Updated the gist and put my essence "lessons learned" into demo.php.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Consider the following PHP code:
You'll see that PHP internally works without leading backslash when passing fully qualified class names around as strings. It isn't super consistent in that. In fact in global scope you can write
\foo\bar
andfoo\bar
and it will behave exactly the same.This has exactly NOTHING to do with TYPO3 background! Devs need to learn and understand that class names passed as strings are in global scope in PHP thus always fully qualified (and preferably without leading slash as it would be redundant). This is true for
class_exists
and frankly even fornew
statements.PHP itself is more graceful than we are now in TYPO3. It strips off the leading slash most of the time, except in bugs that occurred for that reason and obviously in some error messages.
To avoid such bugs, decided to not be graceful and add ltrim statements in every single place we deal with class names as strings but instead throw exceptions in key places so that userland code is forced to not be redundant.
Wrong! makeInstance in 6.2 trims the leading \ and throws an exception in 7.x to avoid further troubles.
It is syntactically and semantically correct in PHP to not use a leading slash for fqcn in global scope.
Hope this made some things clear now