PHP spl_autoload和class_exsits使用技能

2024-05-28 16:58

本文主要是介绍PHP spl_autoload和class_exsits使用技能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文章的PHP使用版本:5.4.7

PHP建议使用:
spl_autoload_register
那么写了一种实现

文件路径

  • core
    • core.php
    • ChildrenClass.php
    • ParentClass.php
  • test
    • index.php

core.php:


<?php/*** Created by PhpStorm.* User: http://blog.csdn.net/cor_twi* Date: 2016/02/25* Time: 11:23*/spl_autoload_register(function ($classId)
{$dirname            = dirname(__FILE__);$classIdParts       = explode("\\", $classId);$classIdLength      = count($classIdParts);$className          = ($classIdParts[$classIdLength - 1]);$defaultNameSpace   = substr(strrchr($dirname,"\\"),1); $namespace          = $classIdLength==1? $defaultNameSpace : $classIdParts[0];for ($i = 1; $i < $classIdLength-1; $i++) {$namespace .= '/' . $classIdParts[$i];}$path = dirname(__FILE__) . "/../" . $namespace . "/" . $className . '.php';$realPath = realpath($path);#print "autoload:realPath:" .  $realPath."\n";if (file_exists($realPath)) {if(!class_exists($className,false)){$ret = include($realPath);print "spl_autoload_  autoload:$className is loaded : result = $ret \n";}elseprint "spl_autoload_ autoload:$className is already loaded\n";}
});

ChildrenClass.php:

<?php
namespace CORE;
use CORE\ParentClass;
/*** Created by PhpStorm.* User: http://blog.csdn.net/cor_twi* Date: 2016/02/22* Time: 9:55*/
class ChildrenClass extends ParentClass
{private $varPro_;public  function __construct($var01,$var02){parent::__construct($var01,$var02);$this->varPro_ = "ChildrenClass";}}

ParentClass.php:

<?php/*** Created by PhpStorm.* User: http://blog.csdn.net/cor_twi* Date: 2016/02/22* Time: 9:40*/
namespace CORE;
class ParentClass
{public static $variable01;public static $variable02;protected  $varPro;/***constructor*/public function __construct($var1,$var2){self::$variable01 = $var1;self::$variable02 = $var2;$this->varPro = "ParentClass";}
}

index.php:

<?php
/*** Created by PhpStorm.* User: http://blog.csdn.net/cor_twi* Date: 2016/03/05* Time: 16:06*/
require('../core/core.php');use CORE\ParentClass;
use CORE\ChildrenClass;print "Section01------------------------\n\n";print "\nSection02------------------------\n\n";$instance01 = new ChildrenClass('aa','vv');
$instance02 = new ParentClass('bb','uu');print "\nSection03------------------------\n\n";
print "Class Load Test-----------------------\n";if(!class_exists('ChildrenClass')){print "\n************\nWarning : in Section 03 : \nClass ChildrenClass is not loaded\n";
}$interfaces = class_implements("ParentClass");print_r($interfaces);
if(isset($interfaces['ParentClass'])){print "OK,PASS";
}
else{print "NO,IT'S NOT";
}print "\nSection04------------------------\n\n";
if(!class_exists('ChildrenClass')){print "\n************\nTEST : in Section 04 : \nClass ChildrenClass is not loaded\n";
}$rc =  new ReflectionClass('ChildrenClass');
try {if($rc->implementsInterface('ParentClass')){print 'imples';}print 'parent class:' . $rc->getParentClass();
}catch(ReflectionException $e){}

然后输出结果是:

J:\xampp\php\php.exe E:\phpStormWorks\php01\test\index.php
Section01------------------------Section02------------------------spl_autoload_  autoload:ParentClass is loaded : result = 1 
spl_autoload_  autoload:ChildrenClass is loaded : result = 1 Section03------------------------Class Load Test-----------------------************
Warning : in Section 03 : 
Class ChildrenClass is not loaded
spl_autoload_  autoload:ParentClass is loaded : result = 1 Warning: class_implements(): Class ParentClass does not exist and could not be loaded in E:\phpStormWorks\php01\test\index.php on line 29Call Stack:0.0008     131888   1. {main}() E:\phpStormWorks\php01\test\index.php:00.0042     147400   2. class_implements() E:\phpStormWorks\php01\test\index.php:29NO,IT'S NOT
Section04------------------------************
TEST : in Section 04 : 
Class ChildrenClass is not loaded
spl_autoload_  autoload:ChildrenClass is loaded : result = 1 Fatal error: Uncaught exception 'ReflectionException' with message 'Class ChildrenClass does not exist' in E:\phpStormWorks\php01\test\index.php on line 46ReflectionException: Class ChildrenClass does not exist in E:\phpStormWorks\php01\test\index.php on line 46Call Stack:0.0008     131888   1. {main}() E:\phpStormWorks\php01\test\index.php:00.0079     147816   2. ReflectionClass->__construct() E:\phpStormWorks\php01\test\index.php:46Process finished with exit code 255

总结:
class_implements()
ReflectionClass()
class_exists()
$interfaces = class_implements(‘\CORE\TestImpl’);
对于当前版本来说:
这几个类的名字必须写use 的短语 as 的也不行:
例如:class_exists(‘\CORE\ParentClass’)
$interfaces[‘CORE\Interf’]
namespace前面的\无所谓
但是interfaces[‘CORE\Interf’] 前面的\有所谓!!!

总结
对于写了namespace的类文件来说,你有两个选择
要么use namespace要么new 和 instanceof 的时候使用namespace,否则出现Fatal error: Class ‘TestImpl’ not found in 即便它正确触发spl_autoload。【原因见后面<Reason>】
要么用namespace前缀来使用这个类符号
如果没有写namespace的呢
没有写namespace的类文件,可以随意使用他的类名字,自动触发spl_autoload注册的函数。
对于类或者接口,class_exsits()和interface_exsits()都如果有他们有namespace需要使用它才能返回正确的结果。
对于class_implements()、ReflectionClass()和implementsInterface(),如果类或者接口具有namespace必须使用带namespace的名称符号来作为参数,否则你将看到:Fatal error: Cannot redeclare class NAMESPACE\XXXXClass in
原因未知:是个bug,经过测试PHP7也有这个问题PHP或许不承认他是个BUG。而且加载器无法检查出来已经被加载。如果你改成class_implements(‘XXXXClass’,false);那么就是[PHP 5.4.7]Warning: class_implements(): Class ChildrenClass does not exist in (即使你写了use)

PHP7:的报错是
PHP Fatal error: Cannot declare class CORE\ChildrenClass, because the name is already in use in E:\phpStormWorks\php01\core\ChildrenClass.php on line 29
PHP Stack trace:
PHP 1. {main}() E:\phpStormWorks\php01\test\index.php:0
PHP 2. class_implements() E:\phpStormWorks\php01\test\index.php:93
PHP 3. spl_autoload_call() E:\phpStormWorks\php01\test\index.php:93

<Reason>:由现象倒推而来,所有的PHP版本,对于有namespace的类或者接口,它是以 带namespace的形式autoload的,不管你写不写use

如果用include_once(),那么不在本文研究范围之内

写的时候手贱文章弄没有了一次,重写之。
测试结论仅供参考。
附上spl_autoload_实现:

<?php/*** Created by PhpStorm.* User: http://blog.csdn.net/cor_twi* Date: 2016/02/25* Time: 11:23*/spl_autoload_register(function ($classId)
{$dirname            = dirname(__FILE__);$classIdParts       = explode("\\", $classId);$classIdLength      = count($classIdParts);$className          = ($classIdParts[$classIdLength - 1]);$defaultNameSpace   = substr(strrchr($dirname,"\\"),1); //here is core$namespace          = $classIdLength==1? $defaultNameSpace : $classIdParts[0];for ($i = 1; $i < $classIdLength-1; $i++) {$namespace .= '/' . $classIdParts[$i];}$path = dirname(__FILE__) . "/../" . $namespace . "/" . $className . '.php';$realPath = realpath($path);#print "autoload:realPath:" .  $realPath."\n";if(class_exists($classId,false)||interface_exists($classId,false)){
//如果代码能进来这个函数说明没有被加载,便不会执行到这里,无法阻止Fatal error: Cannot redeclare classprint "spl_autoload_  preCheck:$className | $classId | is already loaded\n";}if (file_exists($realPath)) {if(class_exists($className,false)||interface_exists($className,false)){print "spl_autoload_  autoload:$className | $classId | is already loaded\n";}else{print "spl_autoload_  autoload: try to load $className | $classId |\n";if ( false ===  include($realPath))print "spl_autoload_  autoload:$className | $classId | failed to be loaded\n";elseprint "spl_autoload_  autoload:$className | $classId | is loaded\n";}}
});

这篇关于PHP spl_autoload和class_exsits使用技能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1011150

相关文章

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

C#中lock关键字的使用小结

《C#中lock关键字的使用小结》在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时,其他线程无法访问同一实例的该代码块,下面就来介绍一下lock关键字的使用... 目录使用方式工作原理注意事项示例代码为什么不能lock值类型在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时