2016年10月

设计模式之建造者模式

// 建造模式(builder)
// 建造者Builder: 规范具体建造者的接口
// 具体建造者Concrete Builder: 实现创建产品的过程, getResult方法返回产品实例
// 指导者Director: 调用具体建造者创建产品对象

interface Builder
{
    public function buildHead($head);

    public function buildBody($body);

    public function buildFoot($foot);

    public function getProduct();
}

class TextBuilder implements Builder
{
    private $product =  array();

    public function buildHead($head)
    {
        $this->product['head'] = $head;
    }

    public function buildBody($body)
    {
        $this->product['body'] = $body;
    }

    public function buildFoot($foot)
    {
        $this->product['foot'] = $foot;
    }

    public function getProduct()
    {
        return $this->product;
    }
}

class XmlBuilder implements Builder
{
    private $product =  array();

    public function buildHead($head)
    {
        $this->product['head'] = '<' . $head . '>';
    }

    public function buildBody($body)
    {
        $this->product['body'] = '<' . $body . '>';
    }

    public function buildFoot($foot)
    {
        $this->product['foot'] = '<' . $foot . '>';
    }

    public function getProduct()
    {
        return $this->product;
    }
}

class Director 
{
    public function __construct(Builder $builder)
    {
        $this->_builder = $builder;
    }

    public function generate($head,$body,$foot)
    {
        $this->_builder->buildHead($head);
        $this->_builder->buildBody($body);
        $this->_builder->buildFoot($foot);
    }
}


$textB = new TextBuilder();
$xmlB = new XmlBuilder();

$director_t = new Director($textB);
$director_t->generate('头部','身体','尾部');

$director_x = new Director($xmlB);
$director_x->generate('头部','身体','尾部');

var_dump($textB->getProduct());
var_dump($xmlB->getProduct());

复习PDO

1.链接

try {
    $dns = 'mysql:host=localhost;dbname=test';
    $attrs = array(
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 
        // 错误处理方式
        // (1)ERRMODE_SILENT 只设置错误码,通过PDO::errorCode,PDO::errorInfo / PDOStatement::errorCode,PDOStatement::errorInfo获取
        // (2)ERRMODE_WARNING, php抛出warning级别错误
        // (3)ERRMODE_EXCEPTION, php抛出PDOException异常
    );
    // 链接选项还可以用'PDO::setAttribute'设置
    $pdo = new PDO($dns,$attrs);

} catch (PDOException $e) {
    echo '链接错误:' . $e->getMessage();
}

2.事务

try {
    $pdo->beginTransaction();
    $pdo->exec(...);
    $pdo->exec(...); // 执行一条语句返回影响的行数
    $pdo->commit();
    // $pdo->rollback();
} catch (PDOException $e) {
    echo '该类型数据库不支持事务';
}

3.预处理

// 绑定参数
$sql_1 = "SELECT * FROM test WHERE username = :username";
$stm = $pdo->prepare($sql_1);
$stm->bindParam(':username',$username);
$username = 'haha';
$stm->execute();

// 绑定值
$sql_2 = "SELECT * FROM test WHERE age = ?";
$stm = $pdo->prepare($sql_2);
$age = 11;
$stm->bindValue(1,$age);
$stm->execute();

4.获取数据

$stm = $pdo->query('SELECT username,age FROM test');

// 单个值
$stm->bindColumn('username',$username);

// 单行
$stm->fetch(PDO::FETCH_BOTH);

// 多行
$stm->fetchAll(PDO::FETCH_BOTH);

// 影响行数
$stm->rowCount();

设计模式之桥接模式

// 桥接方式 (将抽象部分与实现部分分离,使它们都可以独立的变化)
// 例子 : <消息通知> 信息分类作为抽象部分, 信息发送方式作为实现部分
// 桥接,就是让抽象部分拥有实现部分的接口对象

abstract class MsgType
{
    public function __construct(SendMsgOperator $impl) 
    {
        $this->_impl = $impl;
    }

    abstract public function getType();
}


interface SendMsgOperator
{
    public function send($msg);
    public function getType();
}

class SendSms implements SendMsgOperator
{
    public function send($msg)
    {
        echo "发送短信消息:$msg";
    }

    public function getType()
    {
        return '短信';
    }
}

class SendEmail implements SendMsgOperator
{
    public function send($msg)
    {
        echo "发送邮件消息:$msg";
    }

    public function getType()
    {
        return '邮件';
    }
}

class CommonMsg extends MsgType
{
    public function sendMsg($msg)
    {
        $msg = "$msg(普通)";
        $this->_impl->send($msg);
    }

    public function getType()
    {
        return '普通消息';
    }
}

class SpecialMsg extends MsgType
{
    public function sendMsg($msg)
    {
        $msg = "$msg(特别)";
        $this->_impl->send($msg);
    }

    public function getType()
    {
        return '特别消息';
    }
}

// 第三个纬度(抽象)
class LogType
{
    public function __construct(MsgType $msgType)
    {
        $this->_msgType = $msgType;
        $this->msgType = $this->_msgType->getType();
        $this->sendType = $this->_msgType->_impl->getType();
    }

    public function logFile()
    {
        echo <<<EOT
        写入文件 :
        发送类型 : {$this->sendType}
        消息类型 : {$this->msgType}
EOT;
    }

    public function logDb()
    {
        echo <<<EOT
        写入数据库 :
        发送类型 : {$this->sendType}
        消息类型 : {$this->msgType}
EOT;
    }
}



$smsImpl = new SendSms();

$emailImpl = new SendEmail();

$commonMsg = new CommonMsg($smsImpl); // 通过对象组合方式实现桥接

$commonMsg->sendMsg('haha');

echo '<br/>';

$specialMsg = new SpecialMsg($emailImpl);

$specialMsg->sendMsg('kaka');

$fileLog = new LogType($commonMsg);

echo '<br/>';

$fileLog->logFile();

$dbLog = new LogType($specialMsg);

echo '<br/>';

$dbLog->logDb();

git配置SSH免密码登录

生成密钥对

ssh-keygen -t rsa -C "youremail@example.com"

远程主机git用户配置密钥

mkdir /home/git/.ssh
touch /home/git/.ssh/authorized_keys
cat 本机密钥 >> /home/git/.ssh/authorized_keys

修改文件权限

修改 .ssh 目录的权限为 700
修改 .ssh/authorized_keys 文件的权限为 600