cari
Rumahpembangunan bahagian belakangtutorial phpPHP的PSR-0标准利用namespace来做autoloading

介绍PSR-0之前,先来说说命名空间(NameSpace)和Autoloading吧。

NameSpace(命名空间)

namespace是PHP5.3版本加入的新特性,用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题:

1.用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
2.为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。

PHP 命名空间中的元素使用了类似文件系统的原理。例如,类名可以通过三种方式引用:
1.非限定名称,或不包含前缀的类名称,例如 $a=new foo(); 或 foo::staticmethod();。如果当前命名空间是 currentnamespace,foo 将被解析为 currentnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,则 foo 会被解析为foo。 警告:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。详情参见 使用命名空间:后备全局函数名称/常量名称。
2.限定名称,或包含前缀的名称,例如 $a = new subnamespace\foo(); 或 subnamespace\foo::staticmethod();。如果当前的命名空间是 currentnamespace,则 foo 会被解析为 currentnamespace\subnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为subnamespace\foo。
3.完全限定名称,或包含了全局前缀操作符的名称,例如, $a = new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();。在这种情况下,foo 总是被解析为代码中的文字名(literal name)currentnamespace\foo。

另外注意访问任意全局类、函数或常量,都可以使用完全限定名称,例如 \strlen() 或 \Exception 或 \INI_ALL。

<?phpuse My\Full\Classname as Another, My\Full\NSname;$obj = new Another; // 实例化一个 My\Full\Classname 对象$obj = new \Another; // 实例化一个Another对象$obj = new Another\thing; // 实例化一个My\Full\Classname\thing对象$obj = new \Another\thing; // 实例化一个Another\thing对象$a = \strlen('hi'); // 调用全局函数strlen$b = \INI_ALL; // 访问全局常量 INI_ALL$c = new \Exception('error'); // 实例化全局类 Exception?>

以上是namespace的简要介绍,对此不了解的同学还是把细读文档吧。在众多新的PHP项目中,namespace已经被普遍使用了。尤其是伴随Composer的流行,它已经是很有必要去了解的特性了。


Autoloading(自动加载)

很多开发者写面向对象的应用程序时对每个类的定义建立一个 PHP 源文件。一个很大的烦恼是不得不在每个脚本开头写一个长长的包含(require, include)文件列表(每个类一个文件)。

而Autoloading,就是解决这个问题的,通过定义一个/系列autoload函数,它会在试图使用尚未被定义的类时自动调用。通过调用autoload函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。这个autoload函数可以是默认的__autoload(),如下:

<?phpfunction __autoload($class_name) {    require_once $class_name . '.php';}$obj  = new MyClass();
也可以采用更灵活的方式,通过spl_autoload_register()来定义我们自己的__autoload()函数:

<?phpfunction my_autoload($class_name) {	require_once $class_name . '.php';}spl_autoload_register("my_autoload");$obj  = new MyClass();
以上代码将my_autoload()函数注册到__autoload栈中,从而取到__autoload()函数(__autoload()函数将不再起作用,但可以显式的将其注册到__autoload栈)。注意到刚才提到了__autoload栈,意味着我们可以注册多个autoload函数,根据注册的顺序依次加载(通过spl_autoload_register的第三个参数可以改变这一顺序)。

在这里我们展示了autoload函数最简单的例子,当然通过一些规则的设置,也可以胜任实际环境中许多复杂的情况。

但是如果我们的项目依赖某些其他的项目,本来大家在各自独立的加载规则下能顺利运行,但融合在一起可能就不妙了。那么能否有一种通用的加载规则来解决这个问题?

PSR-0

PSR是由PHP Framework Interoperability Group(PHP通用性框架小组)发布的一系列标准/规范,目前包括了PSR-0~PSR-4共4个,而PSR-0就是其中的自动加载标准(其后的PSR-4称为改进的自动加载的标准,是PSR-0的补充。PSR-0使用更广泛)。https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md

下面描述了具体互操作性的自动加载所必须的条件:

强制要求

  • 一个完全合格的namespace和class必须符合这样的结构 \\(\)*
  • 每个namespace必须有一个顶层的namespace("Vendor Name"提供者名字)
  • 每个namespace可以有多个子namespace
  • 当从文件系统中加载时,每个namespace的分隔符要转换成 DIRECTORY_SEPARATOR(操作系统路径分隔符)
  • 在CLASS NAME(类名)中,每个下划线(_)符号要转换成DIRECTORY_SEPARATOR。在namespace中,下划线(_)符号是没有(特殊)意义的。
  • 当从文件系统中载入时,合格的namespace和class一定是以 .php 结尾的
  • verdor name,namespaces,class名可以由大小写字母组合而成(大小写敏感的)
  • 除此之外可能还会遵循这个规则:如果文件不存在则返回false。


    例子

  • \Doctrine\Common\IsolatedClassLoader => /path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php
  • \Symfony\Core\Request => /path/to/project/lib/vendor/Symfony/Core/Request.php
  • \Zend\Acl => /path/to/project/lib/vendor/Zend/Acl.php
  • \Zend\Mail\Message => /path/to/project/lib/vendor/Zend/Mail/Message.php
  • NameSpace和Class Name中的下划线

  • \namespace\package\Class_Name => /path/to/project/lib/vendor/namespace/package/Class/Name.php
  • \namespace\package_name\Class_Name => /path/to/project/lib/vendor/namespace/package_name/Class/Name.php
  • 实现的范例

    下面是一个按照如上标准进行自动加载的简单范例:

    <?phpfunction autoload($className){    //这里的$className一般是用namespace的方式来引用的,文章开头已有介绍    //去除$className左边的'\' 这是PHP5.3的一个bug,详见https://bugs.php.net/50731    $className = ltrim($className, '\\');    $fileName  = '';    $namespace = '';    //找到最后一个namespace分隔符的位置    if ($lastNsPos = strrpos($className, '\\')) {        $namespace = substr($className, 0, $lastNsPos);        $className = substr($className, $lastNsPos + 1);        $fileName  = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;    }    $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';    require $fileName;}

    SplClassLoader 的实现

    下面有一个SplClassLoader 的实现范例,如果你遵循了如上的标准,可以用它来进行自动加载。这也是目前PHP5.3推荐的类加载标准。 http://gist.github.com/221634

    <?php /* * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This software consists of voluntary contributions made by many individuals * and is licensed under the MIT license. For more information, see * <http://www.doctrine-project.org>. */ /** * SplClassLoader implementation that implements the technical interoperability * standards for PHP 5.3 namespaces and class names. * * http://groups.google.com/group/php-standards/web/psr-0-final-proposal?pli=1 * *     // Example which loads classes for the Doctrine Common package in the *     // Doctrine\Common namespace. *     $classLoader = new SplClassLoader('Doctrine\Common', '/path/to/doctrine'); *     $classLoader->register(); * * @license http://www.opensource.org/licenses/mit-license.html  MIT License * @author Jonathan H. Wage <jonwage> * @author Roman S. Borschel <roman> * @author Matthew Weier O'Phinney <matthew> * @author Kris Wallsmith <kris.wallsmith> * @author Fabien Potencier <fabien.potencier> */class SplClassLoader{    private $_fileExtension = '.php';    private $_namespace;    private $_includePath;    private $_namespaceSeparator = '\\';     /**     * Creates a new <tt>SplClassLoader</tt> that loads classes of the     * specified namespace.     *      * @param string $ns The namespace to use.     */    public function __construct($ns = null, $includePath = null)    {        $this->_namespace = $ns;        $this->_includePath = $includePath;    }     /**     * Sets the namespace separator used by classes in the namespace of this class loader.     *      * @param string $sep The separator to use.     */    public function setNamespaceSeparator($sep)    {        $this->_namespaceSeparator = $sep;    }     /**     * Gets the namespace seperator used by classes in the namespace of this class loader.     *     * @return void     */    public function getNamespaceSeparator()    {        return $this->_namespaceSeparator;    }     /**     * Sets the base include path for all class files in the namespace of this class loader.     *      * @param string $includePath     */    public function setIncludePath($includePath)    {        $this->_includePath = $includePath;    }     /**     * Gets the base include path for all class files in the namespace of this class loader.     *     * @return string $includePath     */    public function getIncludePath()    {        return $this->_includePath;    }     /**     * Sets the file extension of class files in the namespace of this class loader.     *      * @param string $fileExtension     */    public function setFileExtension($fileExtension)    {        $this->_fileExtension = $fileExtension;    }     /**     * Gets the file extension of class files in the namespace of this class loader.     *     * @return string $fileExtension     */    public function getFileExtension()    {        return $this->_fileExtension;    }     /**     * Installs this class loader on the SPL autoload stack.     */    public function register()    {        spl_autoload_register(array($this, 'loadClass'));    }     /**     * Uninstalls this class loader from the SPL autoloader stack.     */    public function unregister()    {        spl_autoload_unregister(array($this, 'loadClass'));    }     /**     * Loads the given class or interface.     *     * @param string $className The name of the class to load.     * @return void     */    public function loadClass($className)    {        if (null === $this->_namespace || $this->_namespace.$this->_namespaceSeparator === substr($className, 0, strlen($this->_namespace.$this->_namespaceSeparator))) {            $fileName = '';            $namespace = '';            if (false !== ($lastNsPos = strripos($className, $this->_namespaceSeparator))) {                $namespace = substr($className, 0, $lastNsPos);                $className = substr($className, $lastNsPos + 1);                $fileName = str_replace($this->_namespaceSeparator, DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;            }            $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . $this->_fileExtension;             require ($this->_includePath !== null ? $this->_includePath . DIRECTORY_SEPARATOR : '') . $fileName;        }    }}</fabien.potencier></kris.wallsmith></matthew></roman></jonwage>

    完。


    Kenyataan
    Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
    PHP dan Python: Paradigma yang berbeza dijelaskanPHP dan Python: Paradigma yang berbeza dijelaskanApr 18, 2025 am 12:26 AM

    PHP terutamanya pengaturcaraan prosedur, tetapi juga menyokong pengaturcaraan berorientasikan objek (OOP); Python menyokong pelbagai paradigma, termasuk pengaturcaraan OOP, fungsional dan prosedur. PHP sesuai untuk pembangunan web, dan Python sesuai untuk pelbagai aplikasi seperti analisis data dan pembelajaran mesin.

    PHP dan Python: menyelam mendalam ke dalam sejarah merekaPHP dan Python: menyelam mendalam ke dalam sejarah merekaApr 18, 2025 am 12:25 AM

    PHP berasal pada tahun 1994 dan dibangunkan oleh Rasmuslerdorf. Ia pada asalnya digunakan untuk mengesan pelawat laman web dan secara beransur-ansur berkembang menjadi bahasa skrip sisi pelayan dan digunakan secara meluas dalam pembangunan web. Python telah dibangunkan oleh Guidovan Rossum pada akhir 1980 -an dan pertama kali dikeluarkan pada tahun 1991. Ia menekankan kebolehbacaan dan kesederhanaan kod, dan sesuai untuk pengkomputeran saintifik, analisis data dan bidang lain.

    Memilih antara php dan python: panduanMemilih antara php dan python: panduanApr 18, 2025 am 12:24 AM

    PHP sesuai untuk pembangunan web dan prototaip pesat, dan Python sesuai untuk sains data dan pembelajaran mesin. 1.Php digunakan untuk pembangunan web dinamik, dengan sintaks mudah dan sesuai untuk pembangunan pesat. 2. Python mempunyai sintaks ringkas, sesuai untuk pelbagai bidang, dan mempunyai ekosistem perpustakaan yang kuat.

    PHP dan Rangka Kerja: Memodenkan bahasaPHP dan Rangka Kerja: Memodenkan bahasaApr 18, 2025 am 12:14 AM

    PHP tetap penting dalam proses pemodenan kerana ia menyokong sejumlah besar laman web dan aplikasi dan menyesuaikan diri dengan keperluan pembangunan melalui rangka kerja. 1.Php7 meningkatkan prestasi dan memperkenalkan ciri -ciri baru. 2. Rangka kerja moden seperti Laravel, Symfony dan CodeIgniter memudahkan pembangunan dan meningkatkan kualiti kod. 3. Pengoptimuman prestasi dan amalan terbaik terus meningkatkan kecekapan aplikasi.

    Impak PHP: Pembangunan Web dan seterusnyaImpak PHP: Pembangunan Web dan seterusnyaApr 18, 2025 am 12:10 AM

    Phphassignificantelympactedwebdevelopmentandextendsbeyondit.1) itpowersmajorplatformslikeworderpressandexcelsindatabaseIntions.2) php'SadaptabilityAldoStoScaleforlargeapplicationFrameworksLikelara.3)

    Bagaimanakah jenis membayangkan jenis PHP, termasuk jenis skalar, jenis pulangan, jenis kesatuan, dan jenis yang boleh dibatalkan?Bagaimanakah jenis membayangkan jenis PHP, termasuk jenis skalar, jenis pulangan, jenis kesatuan, dan jenis yang boleh dibatalkan?Apr 17, 2025 am 12:25 AM

    Jenis PHP meminta untuk meningkatkan kualiti kod dan kebolehbacaan. 1) Petua Jenis Skalar: Oleh kerana Php7.0, jenis data asas dibenarkan untuk ditentukan dalam parameter fungsi, seperti INT, Float, dan lain -lain. 2) Return Type Prompt: Pastikan konsistensi jenis nilai pulangan fungsi. 3) Jenis Kesatuan Prompt: Oleh kerana Php8.0, pelbagai jenis dibenarkan untuk ditentukan dalam parameter fungsi atau nilai pulangan. 4) Prompt jenis yang boleh dibatalkan: membolehkan untuk memasukkan nilai null dan mengendalikan fungsi yang boleh mengembalikan nilai null.

    Bagaimanakah PHP mengendalikan pengklonan objek (kata kunci klon) dan kaedah sihir __clone?Bagaimanakah PHP mengendalikan pengklonan objek (kata kunci klon) dan kaedah sihir __clone?Apr 17, 2025 am 12:24 AM

    Dalam PHP, gunakan kata kunci klon untuk membuat salinan objek dan menyesuaikan tingkah laku pengklonan melalui kaedah Magic \ _ _ _. 1. Gunakan kata kunci klon untuk membuat salinan cetek, mengkloning sifat objek tetapi bukan sifat objek. 2. Kaedah klon \ _ \ _ boleh menyalin objek bersarang untuk mengelakkan masalah menyalin cetek. 3. Beri perhatian untuk mengelakkan rujukan pekeliling dan masalah prestasi dalam pengklonan, dan mengoptimumkan operasi pengklonan untuk meningkatkan kecekapan.

    PHP vs Python: Gunakan Kes dan AplikasiPHP vs Python: Gunakan Kes dan AplikasiApr 17, 2025 am 12:23 AM

    PHP sesuai untuk pembangunan web dan sistem pengurusan kandungan, dan Python sesuai untuk sains data, pembelajaran mesin dan skrip automasi. 1.PHP berfungsi dengan baik dalam membina laman web dan aplikasi yang cepat dan berskala dan biasanya digunakan dalam CMS seperti WordPress. 2. Python telah melakukan yang luar biasa dalam bidang sains data dan pembelajaran mesin, dengan perpustakaan yang kaya seperti numpy dan tensorflow.

    See all articles

    Alat AI Hot

    Undresser.AI Undress

    Undresser.AI Undress

    Apl berkuasa AI untuk mencipta foto bogel yang realistik

    AI Clothes Remover

    AI Clothes Remover

    Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

    Undress AI Tool

    Undress AI Tool

    Gambar buka pakaian secara percuma

    Clothoff.io

    Clothoff.io

    Penyingkiran pakaian AI

    AI Hentai Generator

    AI Hentai Generator

    Menjana ai hentai secara percuma.

    Artikel Panas

    R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
    1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. Tetapan grafik terbaik
    1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌
    Akan R.E.P.O. Ada Crossplay?
    1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌

    Alat panas

    Notepad++7.3.1

    Notepad++7.3.1

    Editor kod yang mudah digunakan dan percuma

    ZendStudio 13.5.1 Mac

    ZendStudio 13.5.1 Mac

    Persekitaran pembangunan bersepadu PHP yang berkuasa

    VSCode Windows 64-bit Muat Turun

    VSCode Windows 64-bit Muat Turun

    Editor IDE percuma dan berkuasa yang dilancarkan oleh Microsoft

    MantisBT

    MantisBT

    Mantis ialah alat pengesan kecacatan berasaskan web yang mudah digunakan yang direka untuk membantu dalam pengesanan kecacatan produk. Ia memerlukan PHP, MySQL dan pelayan web. Lihat perkhidmatan demo dan pengehosan kami.

    SecLists

    SecLists

    SecLists ialah rakan penguji keselamatan muktamad. Ia ialah koleksi pelbagai jenis senarai yang kerap digunakan semasa penilaian keselamatan, semuanya di satu tempat. SecLists membantu menjadikan ujian keselamatan lebih cekap dan produktif dengan menyediakan semua senarai yang mungkin diperlukan oleh penguji keselamatan dengan mudah. Jenis senarai termasuk nama pengguna, kata laluan, URL, muatan kabur, corak data sensitif, cangkerang web dan banyak lagi. Penguji hanya boleh menarik repositori ini ke mesin ujian baharu dan dia akan mempunyai akses kepada setiap jenis senarai yang dia perlukan.