Hi php internals,
Currently spl_autoload_register()
pass the name of the class entity to the
first Callable argument, but there is now way (as i far i know) to know
what kind of entity we're looking for.
-Class ?
-Interface ?
-Trait?
A second argument should be added to the Callable function describing
what kind of entity we're looking for.
Example:
<?php
// function __autoload($class) {
// include 'classes/' . $class . '.class.php';
// }
function my_autoloader($entity, $kind = "class") {
// Kind would be: class/interface/trait
include $kind . '/' . $entity . ".{$kind}.php";
}
spl_autoload_register('my_autoloader');
// Or, using an anonymous function as of PHP 5.3.0
spl_autoload_register(function ($entity, $kind = "class") {
// Kind would be: class/interface/trait
include $kind . '/' . $entity . ".{$kind}.php";
});
?>
In fact i think currently that Autoload is too much "class oriented" as per
reading php docs, whereas that php currently allow the autoload of many
entities. It can really confuse probies php developers :(
Pros:
- -Avoid multiple else if() for testing an existing file to load the
entity. - -As we now know the type of entity to load, it help reduce I/O
activity, then reduce timespend. - -Clarify the code: We now what the autoloader will load
- -Keep the BC safe
Cons:
- -None
Regards,
Georges.L
Georges,
Hi php internals,
Currently
spl_autoload_register()
pass the name of the class entity to the
first Callable argument, but there is now way (as i far i know) to know
what kind of entity we're looking for.
-Class ?
-Interface ?
-Trait?A second argument should be added to the Callable function describing
what kind of entity we're looking for.Example:
<?php
// function __autoload($class) {
// include 'classes/' . $class . '.class.php';
// }function my_autoloader($entity, $kind = "class") {
// Kind would be: class/interface/trait
include $kind . '/' . $entity . ".{$kind}.php";
}spl_autoload_register('my_autoloader');
// Or, using an anonymous function as of PHP 5.3.0
spl_autoload_register(function ($entity, $kind = "class") {
// Kind would be: class/interface/trait
include $kind . '/' . $entity . ".{$kind}.php";
});?>
In fact i think currently that Autoload is too much "class oriented" as per
reading php docs, whereas that php currently allow the autoload of many
entities. It can really confuse probies php developers :(Pros:
- -Avoid multiple else if() for testing an existing file to load the
entity.- -As we now know the type of entity to load, it help reduce I/O
activity, then reduce timespend.- -Clarify the code: We now what the autoloader will load
- -Keep the BC safe
Cons:
- -None
This won't work out of the box due to spl_autoload()
. If you use that
default autoloader (by calling spl_autoload_register()
), it will
accept an optional second argument as the list of file extensions.
Which means that having spl_autoload_register()
pass a second argument
to autoloaders will break the existing core autoloader. Changing the
core autoloader is also not really possible due to BC considerations.
So technically, without introducing a new autoload API, this won't
really be possible.
As far as the feature, I would question why you need to distinguish
the file by the type. The names are in the same symbol table, so you
couldn't possibly have a collision. From there, is the identification
of the type of the definition in the filename that important? Isn't
that just another form of Hungarian Notation?
Anthony
Hi php internals,
Currently
spl_autoload_register()
pass the name of the class entity to the
first Callable argument, but there is now way (as i far i know) to know
what kind of entity we're looking for.
-Class ?
-Interface ?
-Trait?A second argument should be added to the Callable function describing
what kind of entity we're looking for.Example:
<?php
// function __autoload($class) {
// include 'classes/' . $class . '.class.php';
// }function my_autoloader($entity, $kind = "class") {
// Kind would be: class/interface/trait
include $kind . '/' . $entity . ".{$kind}.php";
}spl_autoload_register('my_autoloader');
// Or, using an anonymous function as of PHP 5.3.0
spl_autoload_register(function ($entity, $kind = "class") {
// Kind would be: class/interface/trait
include $kind . '/' . $entity . ".{$kind}.php";
});?>
In fact i think currently that Autoload is too much "class oriented" as per
reading php docs, whereas that php currently allow the autoload of many
entities. It can really confuse probies php developers :(Pros:
- -Avoid multiple else if() for testing an existing file to load the
entity.- -As we now know the type of entity to load, it help reduce I/O
activity, then reduce timespend.- -Clarify the code: We now what the autoloader will load
- -Keep the BC safe
Cons:
- -None
Regards,
Georges.L
I'm not sure I agree. Even in your example, the $kind is in the path twice,
which seems redundant. With a good naming system, the namespace and/or
object name will tell you what it is. IE:
Library\Module\DataInterface maps to
/path/to/project/library/module/DataInterface.php
Library\Module\LogInterface maps to
/path/to/project/library/module/LogInterface.php
Library\Traits\Singleton maps to
/path/to/project/library/traits/Singleton.php
Also, check out PSR-0 and PSR-4 (not affiliated with the PHP devs, but
framework owners developing for PHP) which shows how naming conventions
like this can lead to only a single file exists check, further simplifying
the autoloader.
Maybe its not the best code, but this is how simple my autoloader is with a
naming convention like this (Note: DS = DIRECTORY_SEPARATOR
but its too
long):
spl_autoload_register(function ($strClass)
{
$strFile = $strClass . '.php';
$strNameSpace = '';
if ( ($iLast = strripos($strClass, '\')) !== false ) {
$strNameSpace = DS . str_replace('\', DS, substr($strClass, 0,
$iLast));
$strNameSpace = implode('_',
preg_split('/(?<=[a-zA-Z])(?=[A-Z])/s', $strNameSpace));
$strFile = substr($strClass, $iLast + 1) . '.php';
}
$strFilePath = ROOT . strtolower($strNameSpace) . DS . $strFile;
if( is_readable($strFilePath) ) {
require_once $strFilePath;
return true;
}
return false;
});
As you can see, by the result of the naming convention, I know where the
class/interface/trait will be defined based on its namespace and name.
Since traits live under a traits folder, its obvious from their location on
the filesystem what they are (no need to .trait.php at the end).
Additionally since Interface is how all interfaces end in name, the
filename would be redundant to have .interface.php at the end.
-Ryan
Effectively from this perspective, i get it. I'm not a fan of PSR-4
convention as they are not officialy supported by PHP but i understand your
both (Ryan, Anthony) point of view.
Also well done for catching the Hungarian notation, i just noticed that is
a bad pratice.
Anyway, thanks for your (quick) feedback.
Regards.
Geolim4
2015-04-18 17:09 GMT+02:00 Ryan Pallas derokorian@gmail.com:
Hi php internals,
Currently
spl_autoload_register()
pass the name of the class entity to the
first Callable argument, but there is now way (as i far i know) to know
what kind of entity we're looking for.
-Class ?
-Interface ?
-Trait?A second argument should be added to the Callable function describing
what kind of entity we're looking for.Example:
<?php
// function __autoload($class) {
// include 'classes/' . $class . '.class.php';
// }function my_autoloader($entity, $kind = "class") {
// Kind would be: class/interface/trait
include $kind . '/' . $entity . ".{$kind}.php";
}spl_autoload_register('my_autoloader');
// Or, using an anonymous function as of PHP 5.3.0
spl_autoload_register(function ($entity, $kind = "class") {
// Kind would be: class/interface/trait
include $kind . '/' . $entity . ".{$kind}.php";
});?>
In fact i think currently that Autoload is too much "class oriented" as
per
reading php docs, whereas that php currently allow the autoload of many
entities. It can really confuse probies php developers :(Pros:
- -Avoid multiple else if() for testing an existing file to load the
entity.- -As we now know the type of entity to load, it help reduce I/O
activity, then reduce timespend.- -Clarify the code: We now what the autoloader will load
- -Keep the BC safe
Cons:
- -None
Regards,
Georges.LI'm not sure I agree. Even in your example, the $kind is in the path
twice, which seems redundant. With a good naming system, the namespace
and/or object name will tell you what it is. IE:Library\Module\DataInterface maps to
/path/to/project/library/module/DataInterface.php
Library\Module\LogInterface maps to
/path/to/project/library/module/LogInterface.phpLibrary\Traits\Singleton maps to
/path/to/project/library/traits/Singleton.phpAlso, check out PSR-0 and PSR-4 (not affiliated with the PHP devs, but
framework owners developing for PHP) which shows how naming conventions
like this can lead to only a single file exists check, further simplifying
the autoloader.Maybe its not the best code, but this is how simple my autoloader is with
a naming convention like this (Note: DS =DIRECTORY_SEPARATOR
but its too
long):spl_autoload_register(function ($strClass)
{
$strFile = $strClass . '.php';
$strNameSpace = '';
if ( ($iLast = strripos($strClass, '\')) !== false ) {
$strNameSpace = DS . str_replace('\', DS, substr($strClass, 0,
$iLast));
$strNameSpace = implode('_',
preg_split('/(?<=[a-zA-Z])(?=[A-Z])/s', $strNameSpace));
$strFile = substr($strClass, $iLast + 1) . '.php';
}
$strFilePath = ROOT . strtolower($strNameSpace) . DS . $strFile;
if( is_readable($strFilePath) ) {
require_once $strFilePath;
return true;
}
return false;
});As you can see, by the result of the naming convention, I know where the
class/interface/trait will be defined based on its namespace and name.
Since traits live under a traits folder, its obvious from their location on
the filesystem what they are (no need to .trait.php at the end).
Additionally since Interface is how all interfaces end in name, the
filename would be redundant to have .interface.php at the end.-Ryan
Hi php internals,
Currently
spl_autoload_register()
pass the name of the class entity to the
first Callable argument, but there is now way (as i far i know) to know
what kind of entity we're looking for.
-Class ?
-Interface ?
-Trait?A second argument should be added to the Callable function describing
what kind of entity we're looking for.
This is not possible, because we do not generally know if something is a
class or an interface or a trait when autoloading it. E.g. if I write
class_alias('X', 'Y') and X is autoloaded, it could be a class an interface
or a trait - it just doesn't matter.
Nikita
Hi!
Currently
spl_autoload_register()
pass the name of the class entity to the
first Callable argument, but there is now way (as i far i know) to know
what kind of entity we're looking for.
-Class ?
-Interface ?
-Trait?
I'm not sure it would be very useful for the engine. It is obviously
useful for your particular naming scheme, but most people do not use
this scheme, so this is not very common use case. I'd even argue it
usually not the best practice, as class and interface names may be used
interchangeably in typed parameters, return types, instanceof checks,
etc. and one could convert class to interface easily without breaking
anything (except your naming scheme).
Also, while in the many common cases it is known which entity is
required, there's no guarantee it is known in all cases and I'm pretty
sure there could be cases where it's not known - in fact,
zend_lookup_class() API has only the name as its input.
--
Stas Malyshev
smalyshev@gmail.com
De : georges [mailto:geolim4@gmail.com]
Currently
spl_autoload_register()
pass the name of the class entity to the
first Callable argument, but there is now way (as i far i know) to know
what kind of entity we're looking for.
-Class ?
-Interface ?
-Trait?
As others already said, classes, interfaces, and trait names share the same table, and there are a lot of places where you cannot determine the type you're looking for when autoloading a symbol.
However, we'll need to provide a type when we extend autoloading to functions and constants, if we do it someday.
Regards
François
Yes, i finally rewritten major part of my code following the recommended
SF2 standard for naming convention of trait/interfaces.
Thanks Internals.
Regards,
Geo.
Geolim4
2015-04-19 15:33 GMT+02:00 François Laupretre francois@php.net:
De : georges [mailto:geolim4@gmail.com]
Currently
spl_autoload_register()
pass the name of the class entity to
the
first Callable argument, but there is now way (as i far i know) to
know
what kind of entity we're looking for.
-Class ?
-Interface ?
-Trait?As others already said, classes, interfaces, and trait names share the
same table, and there are a lot of places where you cannot determine the
type you're looking for when autoloading a symbol.However, we'll need to provide a type when we extend autoloading to
functions and constants, if we do it someday.Regards
François