PHP的SPL扩展库(四)函数

PHP的SPL扩展库(四)函数

今天我们继续来学习 SPL 中的内容,这篇文章的内容是比较简单的关于 SPL 中所提供的一系列函数相关的内容。其实在之前的不少文章中我们都已经接触过一些 SPL 中提供的函数了。这次我们就详细地再好好学习一下。

类信息相关函数

类信息相关的函数主要都是查看一些类的信息的函数,并没有什么操作类功能的函数。

类的继承、接口、特性查看

首先,我们来看一下,如果想要获得当前类实现了哪个接口,那么我们就直接使用一个 class_implements() 就可以了。

interface A {}
interface B {}

class TestA implements A,B {}

var_dump(class_implements(new TestA));
// array(2) {
//     ["A"]=>
//     string(1) "A"
//     ["B"]=>
//     string(1) "B"
//   }

可以看到,它返回的是一个数组,显示的就是我们当前这个类对象所实现的接口名称。如果我们查询的类没有实现任何接口,那么它返回的就是空的数组。

var_dump(class_implements(new stdClass()));
// array(0) {
// }

同样,我们还可以查看某个类对象的父类。

class C{}

class TestB extends C {}

var_dump(class_parents(new TestB));
// array(1) {
//     ["C"]=>
//     string(1) "C"
//   }

虽说 PHP 是单继承型的语言,但使用 class_parents() 这个函数依然返回的是一个数组。如果类对象没有父类的话,那么也同样返回的是一个空的数组。

class TestC {
    use D, E;
}

var_dump(class_uses(new TestC));
// array(2) {
//     ["D"]=>
//     string(1) "D"
//     ["E"]=>
//     string(1) "E"
//   }

最后,我们还可以通过 class_uses() 函数来获取到当前类对象所使用的 trait 特性信息。

类的哈希及类ID

做过 Java 开发的同学一定都见过所有的类都会有一个 hashCode() 方法。这个方法在 Java 中的作用就是返回一个对象的 Hash 码值。通常用于对象是否相等以及唯一的判断,在 Java 中,所有的类都会默认继承自 Object 这个基类,而这个基类中就自带这个方法。

但是,在 PHP 中,类是没有这样一个全局基类的,自然也就没有这样的方法。显然,只能靠其他的扩展工具帮我们提供这样的能力了。好巧不巧,SPL 中正好就提供了这样的功能。

var_dump(spl_object_hash(new TestA));
// string(32) "000000000ed109570000000025e36d74"

$a = new TestA;
var_dump(spl_object_hash($a));
// string(32) "000000000ed109570000000025e36d74"

var_dump(spl_object_id(new TestA));
// int(2)
var_dump(spl_object_id($a));
// int(1)

spl_object_hash() 函数就是用于获取一个对象的 Hash 值的,它是完整 Hash 值,不像 Java 的 hashCode() 方法返回的是数字类型的值。同样的类模板所实例化的对象返回的内容是一样的。

spl_object_id() 返回的是对象的 ID 。它的结果对于不同的 new ,也就是实例化的对象来说是不同的。如果对象一直存在,那么它的 ID 值是不会发生变化的,而对象被销毁的话,则 ID 值也会被回收并交给其它对象使用。其实直接打印对象我们就可以看到这个 ID 值。

var_dump($a);
// object(TestA)#1 (0) {
// }
var_dump(new TestA);
// object(TestA)#2 (0) {
// }

井号后面的那个数字就是我们对象的 ID 值,也就是 spl_object_id() 所获得的内容。

获取 SPL 库中的所有可用类信息

这个函数返回的是 SPL 这个库中所有的可以使用的类名信息。

var_dump(spl_classes());
// array(55) {
//     ["AppendIterator"]=>
//     string(14) "AppendIterator"
//     ["ArrayIterator"]=>
//     string(13) "ArrayIterator"
//     ["ArrayObject"]=>
//     string(11) "ArrayObject"
//     ["BadFunctionCallException"]=>
//     string(24) "BadFunctionCallException"
//     ["BadMethodCallException"]=>
//     string(22) "BadMethodCallException"
//     ["CachingIterator"]=>
//     string(15) "CachingIterator"
//     ["CallbackFilterIterator"]=>
//     string(22) "CallbackFilterIterator"
//     ["DirectoryIterator"]=>
//     string(17) "DirectoryIterator"
//     ["DomainException"]=>
//     string(15) "DomainException"
//     ["EmptyIterator"]=>
//     string(13) "EmptyIterator"
//     ["FilesystemIterator"]=>
//     string(18) "FilesystemIterator"
//     ["FilterIterator"]=>
//     string(14) "FilterIterator"
//     ["GlobIterator"]=>
// …………………………
// …………………………

可以看到,我们前面讲过的许多类信息在这里都可以看到。

迭代器相关函数

迭代器相关的函数在上一篇文章讲迭代器的时候其实已经出现过了,那就是非常好用的 iterator_to_array() 这个函数。

$iterator = new ArrayIterator(['a'=>'a1', 'b'=>'b1', 'c'=>'c1']);

var_dump(iterator_to_array($iterator, true));
// array(3) {
//     ["a"]=>
//     string(2) "a1"
//     ["b"]=>
//     string(2) "b1"
//     ["c"]=>
//     string(2) "c1"
//   }

我们可以想象成在这个函数内部,其实就是使用 foreach() 遍历了一下这个迭代器,并将所有的结果放在数组中返回回来。这个函数还有第二个参数,它的作用是让键不使用原来的键值,而是使用默认数组下标的方式排列。

var_dump(iterator_to_array($iterator, false));
// array(3) {
//     [0]=>
//     string(2) "a1"
//     [1]=>
//     string(2) "b1"
//     [2]=>
//     string(2) "c1"
//   }

除了直接获得迭代器遍历的结果之外,我们还可以通过一个函数直接获取迭代器内部元素的数量。

var_dump(iterator_count($iterator)); // int(3)

其实 iterator_count() 这个函数就像是 count() 函数的迭代器版本。

function printCaps($iterator){
    echo strtoupper($iterator->current()), PHP_EOL;
    return true;
}
iterator_apply($iterator, "printCaps", array($iterator));
// A1
// B1
// C1

最后这个 iterator_apply() 函数就是让我们可以通过一个指定的回调函数来遍历一个迭代器。

自动加载相关函数

对于自动加载函数来说,我们在最早的文章,也就是讲 Composer 的那一系列文章中就已经接触过了。不过当时我们只是学习了一个 spl_autoload_register() 函数。今天我们就来多学习两个函数,不过首先还是来看看 spl_autoload_register() 函数的使用。

function autoloadA($class){
    if(is_file('./autoloadA/' . $class . '.php')){
        require_once './autoloadA/' . $class . '.php';
    }
    
}
spl_autoload_register('autoloadA');

spl_autoload_register(function($class){
    if(is_file('./autoloadB/' . $class . '.php')){
        require_once './autoloadB/' . $class . '.php';
    }
});

$sky = new Sky();
$sky->result();
// This is Sky PHP!

$planet = new Planet();
$planet->result();
// This is Planet PHP!

在这段测试代码中,我们通过回调函数和匿名函数两种形式注册了两个 spl_autoload_register() 。这样当我们使用当前文件中未定义的类时就会去这两个 autoload 中查找。在之前讲 Composer 时我们就讲过,spl_autoload_register() 比 __autolod() 好的地方就是它维护的是一个自动加载列表,相当于是多个 __autoload() 的功能。我们通过另外一个函数就可以看到当前我们已经注册了多少个自动加载的函数。

var_dump(spl_autoload_functions());
// array(2) {
//     [0]=>
//     string(9) "autoloadA"
//     [1]=>
//     object(Closure)#3 (1) {
//       ["parameter"]=>
//       array(1) {
//         ["$class"]=>
//         string(10) "<required>"
//       }
//     }
//   }

当然,能够不断的注册进来也可以删除掉。

spl_autoload_unregister('autoloadA');

var_dump(spl_autoload_functions());
// array(1) {
//     [0]=>
//     object(Closure)#3 (1) {
//       ["parameter"]=>
//       array(1) {
//         ["$class"]=>
//         string(10) "<required>"
//       }
//     }
//   }

关于 spl_autoload_register() 在实际工程中的应用,也就是 Composer 中的应用,有兴趣的同学可以移步之前的文章。

总结

怎么样,一路看下来是不是发现其实不少的功能大家在日常的开发学习中都已经接触过了。这些函数就是 SPL 扩展库中所提供的功能了,其实通过这几篇文章的学习,我们就已经发现了,SPL 扩展库为我们提供的都是很基础的一些 数据结构 、迭代器、设计模式 之类的功能封装,有很多东西真的比自己实现要简单方便很多,包括我们下一篇还要继续学习的文件操作以及设计模式的实现。

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/2021/01/source/6.PHP的SPL扩展库(四)函数.php

参考文档:

https://www.php.net/manual/zh/ref.spl.php

(0)

相关推荐

  • PHP的SPL扩展库(一)数据结构

    PHP的SPL扩展库(一)数据结构 SPL 库也叫做 PHP 标准库,主要就是用于解决典型问题的一组接口或类的集合.这些典型问题包括什么呢?比如我们今天要讲的数据结构,还有一些设计模式的实现,就像我们 ...

  • PHP的SPL扩展库(二)对象数组与数组迭代器

    PHP的SPL扩展库(二)对象数组与数组迭代器 在 PHP 中,数组可以说是非常强大的一个数据结构类型.甚至我们可以把 PHP 中的数组说成是 PHP 的灵魂,而且这么说一点都不夸张.相比 Java ...

  • PHP的SPL扩展库(三)迭代器

    PHP的SPL扩展库(三)迭代器 关于迭代器,我们在之前设计模式相关的文章中已经讲过迭代器具体是个啥,而且也使用过 SPL 的例子来演示过,要是没有看过之前的文章的可以穿越回去看一下哦!PHP设计模式 ...

  • PHP的SPL扩展库(五)文件及设计模式

    PHP的SPL扩展库(五)文件及设计模式 对于 SPL 来说,除了我们之前学习到的各种 数据结构 以及 迭代器 之外,还有一类非常好用的功能就是对于文件的操作.今天我们就来学习这方面的内容,同时,这也 ...

  • 开源、免费、绿色的屏幕与图像文字识别扩展库

    首先感谢 https://github.com/xuncv/chineseocrlite-aardio 提供的 chineseocrlite-aardio 扩展库,让我了解到了 https://git ...

  • 练习R:lm+plot+abline+text四函数绘制线性拟合散点图

    雇员数据中,我想考察"当前薪金"是不是受到"起始薪金"的影响,通俗理解为"起点越高,发展越好" ? 直接用lm()拟合一个一元线性回归: f ...

  • Open3D面向机器学习的扩展库

    Open3D-ML是Open3D的一个扩展,用于3D机器学习任务.它建立在Open3D核心库之上,并通过机器学习工具对其进行扩展,以进行3D数据处理.此repo集中于语义点云分割等应用程序,并提供可应 ...

  • ASP.NET Core扩展库

    亲爱的.Neter们,在我们日复一日的编码过程中是不是会遇到一些让人烦恼的事情: 日志配置太过复杂,各种模板.参数也搞不清楚,每次都要去查看日志库的文档,还需要复制粘贴一些重复代码,好无赖 当需要类型 ...

  • OGRE 所有版本(从0.1到1.7) (SDK 及 源码 及 扩展库) 下载地址

    Latest 5 files Ogre_iOS_4.3_Dependencies_20110411.dmg application/octet-stream; charset=binary 45.7 ...