以下是一个实现PSR-4规范的例子:
Closure Example
<code><span><?php </span><span>/** * 一个具体项目实现的例子. * 使用SPL注册了autoload函数之后,以下代码将触发autoload函数从 * /path/to/project/src/Baz/Qux.php 文件加载 * \Foo\Bar\Baz\Qux 类 * new \Foo\Bar\Baz\Qux; * *<span> @param</span> string $class The fully-qualified class name. *<span> @return</span> void */</span> spl_autoload_register(<span><span>function</span><span>(<span>$class</span>)</span> {</span><span>// 项目约定的命名空间前缀</span><span>$prefix</span> = <span>'Foo\\Bar\\'</span>; <span>// 命名空间前缀的基础目录</span><span>$base_dir</span> = <span>__DIR__</span> . <span>'/src/'</span>; <span>// 这个类是否使用了命名空间前缀?</span><span>$len</span> = strlen(<span>$prefix</span>); <span>if</span> (strncmp(<span>$prefix</span>, <span>$class</span>, <span>$len</span>) !== <span>0</span>) { <span>// 没有,尝试下个已注册的 autoloader</span><span>return</span>; } <span>// 获取相对类名(截取命名空间前缀后剩下的部分)</span><span>$relative_class</span> = substr(<span>$class</span>, <span>$len</span>); <span>// 用base目录替换命名空间前缀;</span><span>// 用目录分隔符替换命名空间分隔符;</span><span>// 坠上 .php</span><span>$file</span> = <span>$base_dir</span> . str_replace(<span>'\\'</span>, <span>'/'</span>, <span>$relative_class</span>) . <span>'.php'</span>; <span>// 如果文件存在,加载文件。</span><span>if</span> (file_exists(<span>$file</span>)) { <span>require</span><span>$file</span>; } });</span></code>
Class Example
以下是一个处理多命名空间的类的例子。
<code><span><?php </span><span>namespace</span><span>Example</span>; <span>/** * 这个例子是一个针对 一个命名空间前缀对应多个base谬的通用实现。 * * foo-bar 类的包分别在以下路径下... * * /path/to/packages/foo-bar/ * src/ * Baz.php # Foo\Bar\Baz * Qux/ * Quux.php # Foo\Bar\Qux\Quux * tests/ * BazTest.php # Foo\Bar\BazTest * Qux/ * QuuxTest.php # Foo\Bar\Qux\QuuxTest * * ... 以下代码将类文件的路径添加到 \Foo\Bar\命名空间前缀下。 * * <span><?php </span> * // 初始化 loader * $loader = new \Example\Psr4AutoloaderClass; * * // 注册 autoloader * $loader->register(); * * // 为命名空间前缀注册base目录。 * $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/src'); * $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/tests'); * * 下面的代码将触发 autoloader 尝试从 * /path/to/packages/foo-bar/src/Qux/Quux.php 加载 * \Foo\Bar\Qux\Quux 类: * * <span><?php </span> * new \Foo\Bar\Qux\Quux; * * 以下代码触发autoloader尝试从 * /path/to/packages/foo-bar/tests/Qux/QuuxTest.php * 加载\Foo\Bar\Qux\QuuxTest类 : * * <span><?php </span> * new \Foo\Bar\Qux\QuuxTest; */</span><span><span>class</span><span>Psr4AutoloaderClass</span> {</span><span>/** * An associative array where the key is a namespace prefix and the value * is an array of base directories for classes in that namespace. * *<span> @var</span> array */</span><span>protected</span><span>$prefixes</span> = <span>array</span>(); <span>/** * Register loader with SPL autoloader stack. * *<span> @return</span> void */</span><span>public</span><span><span>function</span><span>register</span><span>()</span> {</span> spl_autoload_register(<span>array</span>(<span>$this</span>, <span>'loadClass'</span>)); } <span>/** * Adds a base directory for a namespace prefix. * *<span> @param</span> string $prefix The namespace prefix. *<span> @param</span> string $base_dir A base directory for class files in the * namespace. *<span> @param</span> bool $prepend If true, prepend the base directory to the stack * instead of appending it; this causes it to be searched first rather * than last. *<span> @return</span> void */</span><span>public</span><span><span>function</span><span>addNamespace</span><span>(<span>$prefix</span>, <span>$base_dir</span>, <span>$prepend</span> = false)</span> {</span><span>// normalize namespace prefix</span><span>$prefix</span> = trim(<span>$prefix</span>, <span>'\\'</span>) . <span>'\\'</span>; <span>// normalize the base directory with a trailing separator</span><span>$base_dir</span> = rtrim(<span>$base_dir</span>, DIRECTORY_SEPARATOR) . <span>'/'</span>; <span>// initialize the namespace prefix array</span><span>if</span> (<span>isset</span>(<span>$this</span>->prefixes[<span>$prefix</span>]) === <span>false</span>) { <span>$this</span>->prefixes[<span>$prefix</span>] = <span>array</span>(); } <span>// retain the base directory for the namespace prefix</span><span>if</span> (<span>$prepend</span>) { array_unshift(<span>$this</span>->prefixes[<span>$prefix</span>], <span>$base_dir</span>); } <span>else</span> { array_push(<span>$this</span>->prefixes[<span>$prefix</span>], <span>$base_dir</span>); } } <span>/** * Loads the class file for a given class name. * *<span> @param</span> string $class The fully-qualified class name. *<span> @return</span> mixed The mapped file name on success, or boolean false on * failure. */</span><span>public</span><span><span>function</span><span>loadClass</span><span>(<span>$class</span>)</span> {</span><span>// the current namespace prefix</span><span>$prefix</span> = <span>$class</span>; <span>// work backwards through the namespace names of the fully-qualified</span><span>// class name to find a mapped file name</span><span>while</span> (<span>false</span> !== <span>$pos</span> = strrpos(<span>$prefix</span>, <span>'\\'</span>)) { <span>// retain the trailing namespace separator in the prefix</span><span>$prefix</span> = substr(<span>$class</span>, <span>0</span>, <span>$pos</span> + <span>1</span>); <span>// the rest is the relative class name</span><span>$relative_class</span> = substr(<span>$class</span>, <span>$pos</span> + <span>1</span>); <span>// try to load a mapped file for the prefix and relative class</span><span>$mapped_file</span> = <span>$this</span>->loadMappedFile(<span>$prefix</span>, <span>$relative_class</span>); <span>if</span> (<span>$mapped_file</span>) { <span>return</span><span>$mapped_file</span>; } <span>// remove the trailing namespace separator for the next iteration</span><span>// of strrpos()</span><span>$prefix</span> = rtrim(<span>$prefix</span>, <span>'\\'</span>); } <span>// never found a mapped file</span><span>return</span><span>false</span>; } <span>/** * Load the mapped file for a namespace prefix and relative class. * *<span> @param</span> string $prefix The namespace prefix. *<span> @param</span> string $relative_class The relative class name. *<span> @return</span> mixed Boolean false if no mapped file can be loaded, or the * name of the mapped file that was loaded. */</span><span>protected</span><span><span>function</span><span>loadMappedFile</span><span>(<span>$prefix</span>, <span>$relative_class</span>)</span> {</span><span>// are there any base directories for this namespace prefix?</span><span>if</span> (<span>isset</span>(<span>$this</span>->prefixes[<span>$prefix</span>]) === <span>false</span>) { <span>return</span><span>false</span>; } <span>// look through base directories for this namespace prefix</span><span>foreach</span> (<span>$this</span>->prefixes[<span>$prefix</span>] <span>as</span><span>$base_dir</span>) { <span>// replace the namespace prefix with the base directory,</span><span>// replace namespace separators with directory separators</span><span>// in the relative class name, append with .php</span><span>$file</span> = <span>$base_dir</span> . str_replace(<span>'\\'</span>, <span>'/'</span>, <span>$relative_class</span>) . <span>'.php'</span>; <span>// if the mapped file exists, require it</span><span>if</span> (<span>$this</span>->requireFile(<span>$file</span>)) { <span>// yes, we're done</span><span>return</span><span>$file</span>; } } <span>// never found it</span><span>return</span><span>false</span>; } <span>/** * If a file exists, require it from the file system. * *<span> @param</span> string $file The file to require. *<span> @return</span> bool True if the file exists, false if not. */</span><span>protected</span><span><span>function</span><span>requireFile</span><span>(<span>$file</span>)</span> {</span><span>if</span> (file_exists(<span>$file</span>)) { <span>require</span><span>$file</span>; <span>return</span><span>true</span>; } <span>return</span><span>false</span>; } }</span></span></span></span></code>
Unit Tests
The following example is one way of unit testing the above class loader:
<code><span><?php </span><span>namespace</span><span>Example</span>\<span>Tests</span>; <span><span>class</span><span>MockPsr4AutoloaderClass</span><span>extends</span><span>Psr4AutoloaderClass</span> {</span><span>protected</span><span>$files</span> = <span>array</span>(); <span>public</span><span><span>function</span><span>setFiles</span><span>(array <span>$files</span>)</span> {</span><span>$this</span>->files = <span>$files</span>; } <span>protected</span><span><span>function</span><span>requireFile</span><span>(<span>$file</span>)</span> {</span><span>return</span> in_array(<span>$file</span>, <span>$this</span>->files); } } <span><span>class</span><span>Psr4AutoloaderClassTest</span><span>extends</span> \<span>PHPUnit_Framework_TestCase</span> {</span><span>protected</span><span>$loader</span>; <span>protected</span><span><span>function</span><span>setUp</span><span>()</span> {</span><span>$this</span>->loader = <span>new</span> MockPsr4AutoloaderClass; <span>$this</span>->loader->setFiles(<span>array</span>( <span>'/vendor/foo.bar/src/ClassName.php'</span>, <span>'/vendor/foo.bar/src/DoomClassName.php'</span>, <span>'/vendor/foo.bar/tests/ClassNameTest.php'</span>, <span>'/vendor/foo.bardoom/src/ClassName.php'</span>, <span>'/vendor/foo.bar.baz.dib/src/ClassName.php'</span>, <span>'/vendor/foo.bar.baz.dib.zim.gir/src/ClassName.php'</span>, )); <span>$this</span>->loader->addNamespace( <span>'Foo\Bar'</span>, <span>'/vendor/foo.bar/src'</span> ); <span>$this</span>->loader->addNamespace( <span>'Foo\Bar'</span>, <span>'/vendor/foo.bar/tests'</span> ); <span>$this</span>->loader->addNamespace( <span>'Foo\BarDoom'</span>, <span>'/vendor/foo.bardoom/src'</span> ); <span>$this</span>->loader->addNamespace( <span>'Foo\Bar\Baz\Dib'</span>, <span>'/vendor/foo.bar.baz.dib/src'</span> ); <span>$this</span>->loader->addNamespace( <span>'Foo\Bar\Baz\Dib\Zim\Gir'</span>, <span>'/vendor/foo.bar.baz.dib.zim.gir/src'</span> ); } <span>public</span><span><span>function</span><span>testExistingFile</span><span>()</span> {</span><span>$actual</span> = <span>$this</span>->loader->loadClass(<span>'Foo\Bar\ClassName'</span>); <span>$expect</span> = <span>'/vendor/foo.bar/src/ClassName.php'</span>; <span>$this</span>->assertSame(<span>$expect</span>, <span>$actual</span>); <span>$actual</span> = <span>$this</span>->loader->loadClass(<span>'Foo\Bar\ClassNameTest'</span>); <span>$expect</span> = <span>'/vendor/foo.bar/tests/ClassNameTest.php'</span>; <span>$this</span>->assertSame(<span>$expect</span>, <span>$actual</span>); } <span>public</span><span><span>function</span><span>testMissingFile</span><span>()</span> {</span><span>$actual</span> = <span>$this</span>->loader->loadClass(<span>'No_Vendor\No_Package\NoClass'</span>); <span>$this</span>->assertFalse(<span>$actual</span>); } <span>public</span><span><span>function</span><span>testDeepFile</span><span>()</span> {</span><span>$actual</span> = <span>$this</span>->loader->loadClass(<span>'Foo\Bar\Baz\Dib\Zim\Gir\ClassName'</span>); <span>$expect</span> = <span>'/vendor/foo.bar.baz.dib.zim.gir/src/ClassName.php'</span>; <span>$this</span>->assertSame(<span>$expect</span>, <span>$actual</span>); } <span>public</span><span><span>function</span><span>testConfusion</span><span>()</span> {</span><span>$actual</span> = <span>$this</span>->loader->loadClass(<span>'Foo\Bar\DoomClassName'</span>); <span>$expect</span> = <span>'/vendor/foo.bar/src/DoomClassName.php'</span>; <span>$this</span>->assertSame(<span>$expect</span>, <span>$actual</span>); <span>$actual</span> = <span>$this</span>->loader->loadClass(<span>'Foo\BarDoom\ClassName'</span>); <span>$expect</span> = <span>'/vendor/foo.bardoom/src/ClassName.php'</span>; <span>$this</span>->assertSame(<span>$expect</span>, <span>$actual</span>); } }</span></code>
以上就介绍了PSR-4 实例,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

类和方法的概念和实例类(Class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。方法:类中定义的函数。类的构造方法__init__():类有一个名为init()的特殊方法(构造方法),该方法在类实例化时会自动调用。实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用self修饰的变量。实例化:创建一个类的实例,类的具体对象。继承:即一个派生类(derivedclass)继承基类(baseclass)的

jQuery是一种经典的JavaScript库,被广泛应用于网页开发中,它简化了在网页上处理事件、操作DOM元素和执行动画等操作。在使用jQuery时,经常会遇到需要替换元素的class名的情况,本文将介绍一些实用的方法,以及具体的代码示例。1.使用removeClass()和addClass()方法jQuery提供了removeClass()方法用于删除

class是python中的一个关键字,用来定义一个类,定义类的方法:class后面加一个空格然后加类名;类名规则:首字母大写,如果多个单词用驼峰命名法,如【class Dog()】。

背景最近针对公司框架进行关键业务代码进行加密处理,防止通过jd-gui等反编译工具能够轻松还原工程代码,相关混淆方案配置使用比较复杂且针对springboot项目问题较多,所以针对class文件加密再通过自定义的classloder进行解密加载,此方案并不是绝对安全,只是加大反编译的困难程度,防君子不防小人,整体加密保护流程图如下图所示maven插件加密使用自定义maven插件对编译后指定的class文件进行加密,加密后的class文件拷贝到指定路径,这里是保存到resource/corecla

基本的Java类型(boolean、byte、char、short、int、long、float和double)和关键字void通过class属性也表示为Class对象;Class类中booleanisPrimitive():判定指定的Class对象是否表示一个基本类型。包装类和Void类的静态TYPE字段;Integer.TYPE==int.class;Integer.class==int.class;数组类型的Class实例对象:Classclz=String[].class;数组的Clas

Vue报错:无法正确使用v-bind绑定class和style,怎样解决?在Vue开发中,我们经常会用到v-bind指令来动态绑定class和style,但是有时候我们可能会遇到一些问题,如无法正确使用v-bind绑定class和style。在本篇文章中,我将为你解释这个问题的原因,并提供解决方案。首先,让我们先了解一下v-bind指令。v-bind用于将V

jquery判断元素是否有class的方法:1、通过“hasClass('classname')”方法判断元素是否具有某个class;2、通过“is('.classname')”方法判断元素是否具有某个class。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

SublimeText3汉化版
中文版,非常好用

记事本++7.3.1
好用且免费的代码编辑器

Dreamweaver Mac版
视觉化网页开发工具