邢栋博客

邢栋博客,Action博客,记录工作和生活中的点点滴滴

php简单工厂、工厂模式、抽象工厂实例总结

简单工厂


<?php
/**
 * Created by PhpStorm.
 * User: xingdong
 * Date: 2019/8/3
 * Time: 上午10:05
 */

//简单工厂
interface Product
{
    public function getPrice();
    public function getName();
}

class ProductA implements Product
{
    public function getPrice()
    {
        return 100;
    }

    public function getName()
    {
        return 'ProductA';
    }
}

class ProductB implements Product
{
    public function getPrice()
    {
        return 200;
    }

    public function getName()
    {
        return 'ProductB';
    }
}

class ProductC implements Product
{
    public function getPrice()
    {
        return 300;
    }

    public function getName()
    {
        return 'ProductC';
    }
}

class Factory
{
    public static function createProduct($type)
    {
        $product = null;
        switch ($type){
            case "A":
                $product = new ProductA();
                break;
            case "B":
                $product = new ProductB();
                break;
            case "C":
                $product = new ProductC();
                break;
        }
        return $product;
    }
}


$productA = Factory::createProduct('A');
$productB = Factory::createProduct('B');
$productC = Factory::createProduct('C');


/**
 * 以上便是简单工厂模式的一个典型事例,当用户需要新增产品ProductD时,必须在工厂类的生产方法中增加
对应的判断分支,所以简单工厂模式违背了开放封闭原则。
简单工厂模式,利用静态方法根据输入参数生成对应的产品,隐藏了产品实例化的细节。
总结: 简单工厂模式最大的优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,
对于客户端来说,去除了与具体产品的依赖。但是当需求变动的时候,需要对原有的类进行修改,违背了开放封闭原则。
 *
 *
 */
工厂模式



<?php
/**
 * Created by PhpStorm.
 * User: xingdong
 * Date: 2019/8/3
 * Time: 上午10:05
 */

//工厂方式模式
interface Product
{
    public function getPrice();
    public function getName();
}

class ProductA implements Product
{
    public function getPrice()
    {
        return 100;
    }

    public function getName()
    {
        return 'ProductA';
    }
}

class ProductB implements Product
{
    public function getPrice()
    {
        return 200;
    }

    public function getName()
    {
        return 'ProductB';
    }
}

class ProductC implements Product
{
    public function getPrice()
    {
        return 300;
    }

    public function getName()
    {
        return 'ProductC';
    }
}

interface IFactory{
    public function createProduct();
}

class FactoryA implements IFactory
{
    public function createProduct()
    {
        return new ProductA();
    }
}
class FactoryB implements IFactory
{
    public function createProduct()
    {
        return new ProductB();
    }
}
class FactoryC implements IFactory
{
    public function createProduct()
    {
        return new ProductC();
    }
}

$factoryA = new FactoryA();
$factoryA->createProduct();

$factoryB = new FactoryB();
$factoryB->createProduct();

$factoryC = new FactoryC();
$factoryC->createProduct();

/**
 * 当需要增加一个新产品ProductD,只需要新建对应的FactoryD来实现生产功能即可,对原有的代码
没有任何影响,非常符合开放封闭原则,但是由于每增加一个产品,都需要新增对应的生产工厂,导致增加额外的开发工作量。

总结:由于使用了多态,工厂方法克服了简单工厂违背的开放封闭原则的缺点,又保持了封装对象创建过程的优点。
 */
抽象工厂



<?php
/**
 * Created by PhpStorm.
 * User: xingdong
 * Date: 2019/8/3
 * Time: 上午10:05
 */

//抽象工厂方式
//商品
interface Product
{
    public function getPrice();
    public function getName();
}

class ProductA implements Product
{
    public function getPrice()
    {
        return 100;
    }

    public function getName()
    {
        return 'ProductA';
    }
}

class ProductB implements Product
{
    public function getPrice()
    {
        return 200;
    }

    public function getName()
    {
        return 'ProductB';
    }
}

class ProductC implements Product
{
    public function getPrice()
    {
        return 300;
    }

    public function getName()
    {
        return 'ProductC';
    }
}

//礼品
interface Gift
{
    public function getGiftName();
}

class GiftA implements Gift
{
    public function getGiftName()
    {
        return 'GiftA';
    }
}

class GiftB implements Gift
{
    public function getGiftName()
    {
        return 'GiftB';
    }
}

class GiftC implements Gift
{
    public function getGiftName()
    {
        return 'GiftC';
    }
}

interface IFactory{
    public function createProduct();
    public function createGift();
}

class FactoryA implements IFactory
{
    public function createProduct()
    {
        return new ProductA();
    }

    public function createGift()
    {
        return new GiftA();
    }
}
class FactoryB implements IFactory
{
    public function createProduct()
    {
        return new ProductB();
    }
    public function createGift()
    {
        return new GiftB();
    }
}
class FactoryC implements IFactory
{
    public function createProduct()
    {
        return new ProductC();
    }
    public function createGift()
    {
        return new GiftC();
    }
}

$factoryA = new FactoryA();
$factoryA->createProduct();

$factoryB = new FactoryB();
$factoryB->createProduct();

$factoryC = new FactoryC();
$factoryC->createProduct();

/**
 * 总结:抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需制定他们具体的类。
抽象工厂接口,应该包含所有的产品创建的抽象方法,我们可以定义实现不止一个接口,
一个工厂也可以生产不止一种产品类,和工厂方法模式一样,抽象工厂模式同样实现了开发封闭原则
 */


php之stream_get_line()和fget()读取文件
php之stream_get_line函数和fget函数读取文件

1.txt内容如下
1111111111111111111112111111111111111111111211111111111111233333333333333

stream_get_line示例
<?php
$file_path = './1.txt';
$fp = fopen($file_path, 'r') or die("open file failure!");
$line = 0;
if ($fp) {
    while ($info = stream_get_line($fp, 8192, "2")) {  //以2为分隔符
        $line++;
    }
    fclose($fp); 
}
echo $line; //结果是4


fgets示例
<?php
$file_path = './1.txt';
$fp = fopen($file_path, 'r') or die("open file failure!");
$line = 0;
if ($fp) {
    while ($info = fgets($fp, 8192)) {
        $line++;
    }
    fclose($fp); 
}
echo $line; //结果是1

总结:
stream_get_line()函数与fgets()几乎相同,只是它允许除标准、标准和\r\n之外的行尾分隔符,并且不返回分隔符本身。
php+nginx+mysql+apache查看其编译参数
查看nginx编译参数:/usr/local/nginx/sbin/nginx -V

查看php编译参数:/usr/local/php/bin/php -i | grep configure

查看mysql编译参数:cat /usr/local/mysql/bin/mysqlbug | grep CONFIGURE_LINE //待纠正

查看apache编译参数:cat /usr/local/apache2/build/config.nice   //待认证
php的IteratorAggregate简单事例
<?php
    //IteratorAggregate Generators

    //事例(一)
    class Language implements IteratorAggregate{
        private $names;
        public function __construct(){
            $this->names = explode(',','PHP,JS,JAVA,GO');
        }
        public function getIterator(){
            return new ArrayIterator($this->names);
        }

    }

    $langs = new Language();

    foreach($langs as $lang){
        echo $lang.PHP_EOL;
    }

    //事例(二) 返回一个外部迭代器,可以对数据本身及相关逻辑做更统一的封装
    class Test implements IteratorAggregate{
        private $data;
        public function __construct(array $data){
            $this->data = $data;
        }
        public function getIterator(){
            foreach($this->data as $key=>$value){
                yield $key=>$value;
            }
        }
    }

    $testArr = array(
        'xd'=>100,
        'action'=>123,
        'xingd'=>126
    );
    $test = new Test($testArr);

    foreach($test as $key=>$value){
        echo $key.'-'.$value.PHP_EOL;
    }
php实现单链表
<?php
    class node{
        //初始化变量,包括存储的内容和下一个数据的指针
        public $id = 0;
        public $data = '';
        public $next = null;
        //构造函数,设置存储内容的数据
        public function __construct($id,$nodedata){
            $this->id = $id;
            $this->data = $nodedata;
        }
    }


    class singleLink{
        public $head = '';
        public $size = 0;
        public function  insert($id,$value,$prenodeid = 0){

            $node = new node($id,$value);
            //如果是空链表,直接添加
            if($this->size == 0){
                $this->head = $node;
            }elseif($prenodeid == 0){
                //如果不是空链表,且并没有指定在某一个节点前添加,则在当前节点前添加
                $node->next = $this->head;
                $this->head = $node;
            }else{
                //在某一个节点后添加新节点
                $currentnode = $this->head;
                while($currentnode->next != null) {
                    if ($currentnode->next->id == $prenodeid) {
                        $node->next = $currentnode->next;
                        $currentnode->next = $node;
                        break;
                    }
                    $currentnode = $currentnode->next;
                }
            }

            $this->size++;

            return $this;
        }

        public function edit($id,$value){
            $flag = false;
            $current = $this->head;
            while(@$current->id != null){
                if($current->id == $id){
                    $current->data = $value;
                    $flag = true;
                    break;
                }
                $current = $current->next;
            }
            return $flag;
        }


        public function get($id=0){
            $current = $this->head;
            while(@$current->id != null){
                if($id != 0 && $current->id == $id){
                    $node = $current;
                    break;
                }else{
                    $node[] = array($current->id,$current->data);
                }
                $current = $current->next;
            }
            return $node;
        }


        public function delete($id){
            $flag = false;
            $current = $this->head;
            while(@$current->id != null){
                if($current->next->id == $id){
                    $current->next = $current->next->next;
                    $this->size--;
                    $flag = true;
                    break;
                }

                $current = $current->next;
            }
            return $flag;
        }

    }


    $linklist = new singleLink();
    $linklist->insert(1,'hello1');
    $linklist->insert(2,'hello2');
    $linklist->insert(3,'hello3');
    $linklist->insert(4,'hello4');
    $linklist->insert(5,'hello5');
    $linklist->insert(6,'hello6',2);
    $linklist->insert(7,'hello7');

    $linklist->delete(5);

    $linklist->insert(8,'hello8')->insert(9,'hello9')->insert(10,'hello10');

    echo "<pre>";
    print_r($linklist);
    print_r($linklist->get());
php使用mongo的GridFS存储文件
<?php
    //php使用mongo的GridFS存储文件
    $conn = new MongoClient();
    $db = $conn->photos;
    $collection = $db->getGridFS();

    //存储文件
    $id = $collection->storeFile('./logo22.png');

    //存储文件二进制流
//    $data = file_get_contents('./logo22.png');
//    $id = $collection->storeBytes($data,array('param'=>'logo图片'));

    //保存
    //$id = $collection->storeUpload('upfile');
    //相当于
    //$id = $collection->storeFile($_FILES['upfile']['tmp_name']);

    //读取
    $logo = $collection->findOne(array('_id'=>$id));
    header('Content-type:image/png');//输出图片头
    //var_dump($logo);
    echo $logo->getBytes();

php实现http401授权
<?php

//unset($_SERVER['PHP_AUTH_DIGEST']);

$username = 'xingdong'; //用户名
$userpass = '123456'; //面膜
$secret = 'xingdong365'; //秘钥

$realm = '401test';

$opaque = md5($secret.$_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR']);

if (!isset($_SERVER['PHP_AUTH_DIGEST']) || empty($_SERVER['PHP_AUTH_DIGEST'])) {
    header('HTTP/1.1 401 Unauthorized');
    header('WWW-Authenticate: Digest realm="'.$realm.'",qop="auth",nonce="'.uniqid().'",opaque="'.$opaque.'"');
    die;
}

$needed_parts = array(
    'nonce'    => 1,
    'nc'       => 1,
    'cnonce'   => 1,
    'qop'      => 1,
    'username' => 1,
    'uri'      => 1,
    'response' => 1
);

$data = array();
$keys = implode('|', array_keys($needed_parts));

preg_match_all('/('.$keys.')=(?:([\'"])([^\2]+?)\2|([^\s,]+))/', $_SERVER['PHP_AUTH_DIGEST'], $matches, PREG_SET_ORDER);

foreach ($matches as $m) {
    $data[$m[1]] = $m[3] ? $m[3] : $m[4];
    unset($needed_parts[$m[1]]);
}

//检测用户名
if ($data['username'] != $username){
    header('HTTP/1.1 401 Unauthorized');
    header('WWW-Authenticate: Digest realm="'.$realm.'",qop="auth",nonce="'.uniqid().'",opaque="'.$opaque.'"');
    die('Invalid username.');
}

$password = md5($username.':'.$realm.':'.$userpass);

$response = md5($password.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']));



if ($data['response'] != $response) {
    header('HTTP/1.1 401 Unauthorized');
    header('WWW-Authenticate: Digest realm="'.$realm.'",qop="auth",nonce="'.uniqid().'",opaque="'.$opaque.'"');
    die('Invalid password.');
}


echo "success";

php代码执行过程简述
php代码的执行过程

扫描->解析->编译->执行->输出

1.扫描(scanning) 将index.php内容变成一个个语言片段(token)
<?php

$code =<<<'PHP_CODE'
<?php
//这是注释
echo "hello world\n";
$data = 1+1;
eval("echo 'Inception lvl 1...\n';");
echo $data;
PHP_CODE;
echo "<pre>";
print_r(token_get_all($code));

echo token_name(319);//输出 T_ECHO  ,260 T_EVAL(eval不是函数)

/*
 *   [16] => Array
        (
            [0] => 319  //tokenid,也就是词的id
            [1] => echo  //词具体的内容
            [2] => 5 //所在的位置,行数
        )
 *
 */

?>

2.解析(parsing) 将一个个语言片段变成有意义的表达式
3.编译(complication) 将表达式编译成中间码(opcode)  //可以使用vld扩展或者parsekit扩展查看
4.执行(execution) 将中间码一条条的执行
如果执行的是某内置函数,会调用对应的函数;
如果调用的是扩展,则会将控制权交给这些扩展,扩展执行完成后将结果返回给 zend engine
全部执行完成后zend engine将结果返回给php内核,内核再返回给sapi,最后返回给服务器,通过服务器httpresponse返回到浏览器

5.输出(output buffer) 将要输出的内容输出到缓冲区


优惠券
广告位-淘宝
最新微语