php调用静态方法-关于PHP中static和yield关键字的思考

2023-08-27 0 7,136 百度已收录

我很高兴能够激活原来的功能。

你以为你知道一切,但你只是这么想。 知识的美妙之处在于生命在它面前变得多么短暂。

好吧,扯远了,我只是想谈谈昨天的事情:static 和yield。

我们先来说说static关键字。 本文只讲静态方法的使用以及后期绑定的知识点。

何时使用静态来修改技能

大家都知道static关键字是用来修饰方法和属性的。 那么你的项目中会在什么场景下使用它呢?

我遇到过几个项目,要求所有方法都是静态的。 事实上,控制器方法无法做到这一点。 原因之一是:静态模式执行效率高? 那么我们就基于此来分析一下。

首先,执行效率高我没有问题。 那么是不是因为它的效率高php调用静态方法,就应该在项目中不受限制地使用呢? 为了讨论这个问题,我们先回顾一下编程语言的历史。 早期没有面向对象,采用的是结构化编程。 那时基本上所有的方法都是静态方法。 后来有了面向对象,就形成了实例化的概念。

php调用静态方法-关于PHP中static和yield关键字的思考

从里面简单的开发流程可以看出,如果只是为了性能,那么面向对象似乎没有必要。 那么为了让这样的高手将面向对象和实例化引入到c++java语言中呢? 我想是因为随着发展,项目越来越大,需要更好的组织代码方法和编程思维。

回头看static,它定义的静态方法确实效率很高,而且会持续占用显存。 只有当程序退出时,生命周期才会结束。 三是期间未能销毁的副作用; 首先是来自设计模式。 据说耦合性强,静态属性可以外部改变; 一是静态定义方法没有办法重写重绘,iocdi等概念没用; 一是静态方法在进行单元测试时很让人头疼。

那么通过我之前说的,我觉得以后最好不要使用静态方法,而是实例化后调用方法? 我们要理智,不能处处走极端,也不能什么都不用。 一句话:学会以面向对象的方式思考。 我感觉我们写代码首先考虑的是:可扩展性(应对业务的快速变化)、可维护性(及时修复线上问题)。 高效率应该是最后考虑的(​​因为优化效率的方法有很多,所以没必要给每个方法都加上:static)。 如果从面向对象的角度来看,这个方法是完全独立的,与类属性无关,那就用static。

其实从面向对象的角度来看,句型的使用是在软件设计层面考虑的,而不是为了效率而破坏代码的美观。

静态后期静态绑定

这一点在php文档中已经有详细的介绍了,我对这个地方还是不太关注,基本上都是使用self::方法来调用静态方法和属性。

php调用静态方法-关于PHP中static和yield关键字的思考

我认为后期绑定有点像静态方法的重载。下面是php文档中的一个示例来声明

<?phpclass A {    public static function who() {        echo __CLASS__;
    }    public static function test() {        self::who();        static::who();// 后期静态绑定
    }
}class B extends A {    public static function who() {        echo __CLASS__;
    }
}
B::test();

如果是self::who()调用,会输出:A。如果是static::who(),会输出B

从这个角度来看,是不是就相当于classB重绘了父类A的who()方法呢? 所以如果灵活运用这个特性,就可以让static变得更加灵活。 充分发挥其性能优势,解决扩展性差的问题。 其实还是一样。 从面向对象的角度来看,一切就足够了。

PHP中yield的使用场景

说实话,很长一段时间我都不知道PHP还有这样的句型。 直到三天前,我在js中遇到了这个关键字,感觉这么一个未知的东西,世界上怎么可能没有最好的语言呢? 回顾一下文档,确实如此php调用静态方法,而且它当之无愧地成为世界上最好的语言。

php调用静态方法-关于PHP中static和yield关键字的思考

这样的yield有哪些使用场景呢? 就在最近,有人在sg问我,我来整理一下。 希望大家能更多的结合自己的业务来使用。 这里没有对yield和Iterator进行比较。 相信看完之后你就能明白两者哪个更简短了。

先说一下它的使用场景。 我们还是要回顾一下历史。 在有yield之前,我们需要生成一个链表,并且一次只能将所有内容读入显存(其实也可以通过实现Iterator套接字来实现一次迭代)。 有了yield,我们可以通过一个简单的yield关键字来完成链表的生成,但是当它使用的时候,就会形成一个值,相对来说,内存占用肯定会增加。 空话没有证据,我们来实际测试一下下面代码中的推论。

首先看普通模式

<?phpfunction generateData($max){    $arr = [];    for ($i = 0; $i <= $max; $i++) {        $arr[] = $i;
    }
}echo '开始前内存占用:' . memory_get_usage() . PHP_EOL;$data = generateData(100000);echo '生成完数组后内存占用:' . memory_get_usage() . PHP_EOL;unset($data);echo '释放后的内存占用:' . memory_get_usage() . PHP_EOL;

运行即可得到结果:

开始前内存占用:231528
生成完数组后内存占用:231712
释放后的内存占用:231576

php调用静态方法-关于PHP中static和yield关键字的思考

前后差异为:184

使用yield后的疗效

function generateData($max){  for ($i = 0; $i <= $max; $i++) {      yield $i;
  }
}echo '开始前内存占用:' . memory_get_usage() . PHP_EOL;$data = generateData(100000);// 这里实际上得到的是一个迭代器echo '生成完数组后内存占用:' . memory_get_usage() . PHP_EOL;unset($data);echo '释放后的内存占用:' . memory_get_usage() . PHP_EOL;

运行结果:

开始前内存占用:228968
生成完数组后内存占用:229824
释放后的内存占用:229016

前后差异为:856

奇怪的是,使用yield后,显存占用居然增加了。 这是什么鬼? 不用担心。 我们之前传入的参数是1,000,00。 现在我将尝试将参数更改为 1,000,000。

第一种方法的结果是:

开始前内存占用:231528
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in /test/yield.php on line 6

看看吧,一百万个周期,一次性加载显存,超出极限了。 我们再看一下yield的执行结果:

开始前内存占用:228968
生成完数组后内存占用:229824
释放后的内存占用:229016

前后差值依然是:856

好吧,此时,您应该看到,无论字段大小如何,yield 都占据 856。 这是因为它本身,当你迭代的时候它就会形成真实的数据。

所以如果你的数据源非常大,就这样使用yield。 如果数据源很小,其实选择加载显存一次即可。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 php php调用静态方法-关于PHP中static和yield关键字的思考 https://www.wkzy.net/game/165890.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务