75142913在线留言
【PHP进阶】开发模式与内存优化_PHP技术_网络人

【PHP进阶】开发模式与内存优化

Kwok 发表于:2022-06-29 19:29:43 点击:193 评论: 0

在一些大型项目中,或者对安全、性能有一定要求的项目中,我们通常会引用一个三私一公的开发模式,用于限制内存的使用。也可能会使用工厂模式生成新对象。下面针对性能优化及开发技巧做一些说明。

一、单例模式

singleton,是一种类的设计只会最多产生一个对象的设计思想:

  • 单例模式的类只能在一次运行中产生一个对象
  • 单例模式为了解决如何只产生一个对象,需要使用以下解決方案,简称三私一公:
  • 私有化构造方法:不让在外部产生多个对象
  • 私有化克隆方法:不允许对象被克隆产生新对象
  • 公有化静态方法:运行进入类内部产生对象
  • 私有化静态属性:保存已经产生的对象
class Singleton
{
    //1、私有化构造方法:防止外部无限实例化对多
    private function __construct(){
        //没有初始化需求的话,构造方法可以为空方法
    }
    //2、私有化静态属性以保存产生的对象
    private static $obj = NULL;
    //3、私有化克隆方法。防止产生新的对象
    private function __clone(){}
    //4、公开静态的创建对象方法
    public static function getInstance(){
        if (!self::$obj instanceof self) {
            self::$obj = new self();//对象不存在则new一个。
        }
        return self::$obj;//返回对象
    }
}

二、工厂模式

上面的单例模式可以返回一个对象,并不会开辟新的内存。可以做到一点内存的优化工作。这里我们将学习通过工厂模式,批量生产对象。factory,是指像工厂一样流水线生产对象,由一个地方生产对象,其他位置就不需要额外实例化对象,从而可以方便后期代码统一的维护。

  • 工厂模式是用来代生产对象
  • 工厂模式下可以方便隐藏真实的类结构,因此也更加安全
  • 工厂模式不需要关注工厂是如何产生对象,只需要让工厂产生对象
class ObjFactory
{
    //通过不同的flag返回不同的类对象
    public static function getInstance($flag = 'man')
    {
        switch ($flag) {
            case 'man':
                return new humanman();
            case 'woman':
                return new humanwoman();
            case 'renyao':
                return new humanladyboy();
            default:
                return null;
        }
    }
}

 1、工厂模式是一种按需生产对象的模式(一个工厂生产的对象应该相似)

2、工厂模式通常是需要在大型项目中,会出现很多的相同功能的美,此时可以使用工厂产生对象

3、工厂模式的优点是能够方便后期对类的维护(更名)

4、工厂模式的缺点是随着功能增加,会需要增加很多开发量(开发多个工厂):以上只是一种简单工厂模式,复杂的工厂模式会有不同的工厂,调用时需要使用不同工厂来实现对象生产。

三、Generator 生成器

Generator,生成器提供了一种更容易的方法来实现简单的对象迭代。相比较定义类实现 lterator 接口的方式,性能开销和复杂性大大降低

•生成器是一个类Generator实现了lterator接口,并且实现了lterator方法(修改了内部逻辑)

•生成器是暂停循环执行逻辑,等到使用到的时候才触发循环再次执行。

1、常规的循环代码

function getArr()
{
    $arr = []; //初始化数组
    for ($i = 0; $i < 100000; $i++) {
        $arr[] = $i;
    }
    return $arr;//返回包含了$i个值的数组
}

2、使用生成器优化内存

function getArr()
{
    for ($i = 0; $i < 100000; $i++) {
       yield $i;//遍历一次取一次,内存里只保存当前的$i
    }
}

使用yield关键可以只将当前被遍历的值放入内存中,大大的减少了内存操作与使用量。特别是在数据库查询遍历时。推荐优先优化些方式。

 四、Iterator迭代器

 PHP内置的一种能够多修改foreach内部运行机制的接口,lterator迭代器内置了5个抽象方法,实现迭代器的类必须实现5个抽象方法。实现了iterator迭代器的类的对象在进行foreach时,不会按照foreach原来的机制处理,而是调用迭代器的5个方法:

foreach本身的执行步骤

  1. 初始化目标:将对象指针指向第一个属性(执行一次)
  2. 判定指针是否有效:判定当前指针指向的元素是否存在,存在下一步,不存在终止 (N+1次执行)
  3. 取出当期指针元素下标(属性名):将当前属性的名字取出来存储到变量 (N次执行)
  4. 取出当前指针元素值(属性值):将当前属性的值取出来存储到变量(N次执行)
  5. 将指针指向下一个:将取出元素后的指针指向下一个属性 (N次执行)
Iterator extends Traversable{
   abstract public current(): mixed — 返回当前元素
   abstract public key(): scalar — 返回当前元素的键
   abstract public next(): void — 向前移动到下一个元素
   abstract public rewind(): void — 返回到迭代器的第一个元素
   abstract public valid(): bool — 检查当前位置是否有效
}

具体实现Iterator接口的代码演示:

class MyIterator implements Iterator
{
    private $var = array();

    public function __construct($array)
    {
        if (is_array($array)) {
            $this->var = $array;
        }
    }

    public function rewind()
    {
        echo "倒回第一个元素n";
        reset($this->var);
    }

    public function current()
    {
        $var = current($this->var);
        echo "当前元素: $varn";
        return $var;
    }

    public function key()
    {
        $var = key($this->var);
        echo "当前元素的键: $varn";
        return $var;
    }

    public function next()
    {
        $var = next($this->var);
        echo "移向下一个元素: $varn";
        return $var;
    }


    public function valid()
    {
        $var = $this->current() !== false;
        echo "检查有效性: {$var}n";
        return $var;
    }
}


$values = array(1, 2, 3);
$it = new MyIterator($values);
foreach ($it as $k => $v) {
    print "此时键值对 -- key $k: value $vnn";
}
除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/233
标签:PHP开发模式内存优化Kwok最后编辑于:2022-06-29 19:29:10
0
感谢打赏!

《【PHP进阶】开发模式与内存优化》的网友评论(0)

本站推荐阅读

热门点击文章