本文的示例代码参考autoload
目录
环境
sudo apt install -y \
php7.0 \
php7.0-curl \
php7.0-json \
php7.0-cgi \
php7.0-fpm \
autoconf \
automake \
libxml2-dev \
libcurl4-openssl-dev \
libssl-dev \
openssl \
gettext \
libicu-dev \
libmcrypt-dev \
libmcrypt4 \
libbz2-dev \
libreadline-dev \
build-essential \
libmhash-dev \
libmhash2 \
libxslt1-dev
相关依赖参考 Requirement - Ubuntu 16.04
curl -L -O https://github.com/phpbrew/phpbrew/raw/master/phpbrew
chmod +x phpbrew && sudo mv phpbrew /usr/local/bin/phpbrew
phpbrew init
cat ~/.phpbrew/bashrc >> ~/.bashrc && . ~/.bashrc
phpbrew known
phpbrew install 7.1.0
phpbrew use 7.1.0 && php -v
开始
vim startup.php
<?php
class Person
{
var $name, $age;
function __construct($name, $age)
{
$this->name = $name;
$this->age = $age;
}
}
$person = new Person("David", 6);
var_dump($person);
PHP语法参考 X分钟速成Y - 其中 Y=PHP
php startup.php
object(Person)#1 (2) {
["name"]=>
string(5) "David"
["age"]=>
int(6)
}
没有autoload
vim Person.php
<?php
class Person
{
var $name, $age;
function __construct($name, $age)
{
$this->name = $name;
$this->age = $age;
}
}
vim no_autoload.php
<?php
require_once "Person.php";
$person = new Person("David", 6);
var_dump($person);
php no_autoload.php
object(Person)#1 (2) {
["name"]=>
string(5) "David"
["age"]=>
int(6)
}
include与require的区别参考 PHP中include和require的区别详解 / php中return,require,include加括号和不加括号的区别
PHP autoload
vim php_autoload.php
<?php
function __autoload($class_name)
{
echo "__autoload classname: ".$class_name."\n";
$class_path = "./".$class_name.'.php';
if(file_exists($class_path))
{
require_once $class_path;
}
else
{
echo 'class file'.$class_path.'not found!';
}
}
$person = new Person("David", 6);
var_dump($person);
php php_autoload.php
__autoload classname: Person
object(Person)#1 (2) {
["name"]=>
string(5) "David"
["age"]=>
int(6)
}
SPL autoload
The Standard PHP Library(SPL) is a collection of interfaces and classes that are meant to solve common problems
vim spl_autoload.php
<?php
function autoload_in_dir($class_name, $dir) {
echo "autoload in ".$dir." classname: ".$class_name."\n";
$class_path = $dir.$class_name.'.php';
if(file_exists($class_path))
{
require_once $class_path;
}
else
{
echo 'class file'.$class_path.'not found!';
}
}
function autoload_in_current_dir($class_name) {
autoload_in_dir($class_name, "./");
}
spl_autoload_register("autoload_in_current_dir");
$person = new Person("David", 6);
var_dump($person);
php spl_autoload.php
autoload in ./ classname: Person
object(Person)#1 (2) {
["name"]=>
string(5) "David"
["age"]=>
int(6)
}
vim spl_autoload.php
<?php
function autoload_in_dir($class_name, $dir) {
echo "autoload in ".$dir." classname: ".$class_name."\n";
$class_path = $dir.$class_name.'.php';
if(file_exists($class_path))
{
require_once $class_path;
}
else
{
echo 'class file'.$class_path.'not found!';
}
}
function autoload_in_current_dir($class_name) {
autoload_in_dir($class_name, "./");
}
function autoload_in_parent_dir($class_name) {
autoload_in_dir($class_name, "../");
}
spl_autoload_register("autoload_in_current_dir");
spl_autoload_unregister("autoload_in_current_dir");
spl_autoload_register("autoload_in_parent_dir");
$person = new Person("David", 6);
var_dump($person);
php spl_autoload.php
autoload in ../ classname: Person
class file../Person.phpnot found!PHP Fatal error: Uncaught Error: Class 'Person' not found in /Users/kevin/Workspace/php-tutorial/autoload/spl_autoload.php:28
Composer autoload
Composer详细介绍参考 Composer 中文文档
composer.json
cat composer.json
# 其他略过
"autoload": {
"psr-4": {
"Base\\": "module/Base/"
}
},
# 其他略过
Composer autoload参考 Composer 中文文档 - 基本用法
vendor/autoload.php
cat vendor/autoload.php
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit2d9e6983d02eaab8b6b26ee749ae9efa::getLoader();
vendor/composer/autoload_real.php
cat vendor/composer/autoload_real.php
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit2d9e6983d02eaab8b6b26ee749ae9efa
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$loader->register(true);
return $loader;
}
}
为叙述问题方便 这里只保留核心代码 以下也相同处理
vendor/composer/autoload_psr4.php
cat vendor/composer/autoload_psr4.php
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Base\\' => array($baseDir . '/module/Base'),
);
vendor/composer/ClassLoader.php
cat vendor/composer/ClassLoader.php
<?php
namespace Composer\Autoload;
class ClassLoader
{
// PSR-4
private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array();
private $fallbackDirsPsr4 = array();
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
}
}