PHP连接MYSQL单例模式

<?php
class Database{
    private $host    ='localhost'; //数据库主机
    private $user     = 'root'; //数据库用户名
    private $pwd     = ''; //数据库用户名密码
    private $database = ''; //数据库名
    private $charset = 'utf8'; //数据库编码,GBK,UTF8,gb2312
    private $link;             //数据库连接标识;
    private $rows;             //查询获取的多行数组
    static $_instance; //存储对象
    /**
     * 构造函数
     * 私有
     */
    private function __construct($pconnect = false) {
        if (!$pconnect) {
            $this->link = @ mysql_connect($this->host, $this->user, $this->pwd) or $this->err();
        } else {
            $this->link = @ mysql_pconnect($this->host, $this->user, $this->pwd) or $this->err();
        }
        mysql_select_db($this->database) or $this->err();
        $this->query("SET NAMES '{$this->charset}'", $this->link);
        return $this->link;
    }
    /**
     * 防止被克隆
     *
     */
    private function __clone(){}
    public static function getInstance($pconnect = false){
        if(FALSE == (self::$_instance instanceof self)){
            self::$_instance = new self($pconnect);
        }
        return self::$_instance;
    }
    /**
     * 查询
     */
    public function query($sql, $link = '') {
        $this->result = mysql_query($sql, $this->link) or $this->err($sql);
        return $this->result;
    }
    /**
     * 错误信息输出
     */
    protected function err($sql = null) {
        //这里输出错误信息
        echo 'error';
        exit();
    }
}

PHP命令行消息处理程序

<?php
while (true) {
        $pid = pcntl_fork();
        if ($pid == -1) {
            echo date('Y-m-d H:i:s') . "fork失败!\n";
        } else if ($pid == 0) {
            $redis = new Redis();
            $redis->connect('127.0.0.1', 6379);
            //code here
            exit;
        } else {
            pcntl_wait($status);
        }
}

pcntl_fork是PHP中的生成子进程,当调用该函数时,会返回一个进程pid,当pid为0时表明是在子进程中,所以把要执行的东西全放这里

PHP安装redis扩展模块

每次要用redis都要引入外部库,突然想到为什么不能用php扩展模块的方式来调用redis,毕竟PHP的extension是很强大的。
于是找了一下还真有。
说一下安装过程
https://github.com/phpredis/phpredis
在这里获取phpredis的最新安装包
然后unzip或者tar解压。
先使用phpize得到configure文件,然后执行./configure --with-php-config=/usr/local/php/bin/php-config
然后make && make install
这样就在extension目录里产生了一个redis.so文件
我们要在php.ini里面载入它
在php.ini中加入

[redis]
extension=redis.so

重启一下php-fpm。然后进phpinfo()看一下。有redis就成功了。调用方法稍后再写。

赞一下Vultr的客服

今晚遇到的奇葩事情也是多。刚才在Vultr的两台VPS之间正通过private network传输数据呢
突然后悬挂(大雾)就断了,然后就再也ping不通对方了。
ifup,ifconfig eth1 up都试了也没有用。就差报警了。
这时机智的我去Support发了一个ticket。
没想到不到两分钟客服就回了

Hello,

This is a known issue. We have implemented updates to our network
infrastructure and would like to refresh your existing instance(s) to
resolve the underlying issue. This will require us to restart your
instance so just let us know when we can do this for you.

PLEASE NOTE: You may not perform this restart yourself; we must
perform this for you and the restart window should be less than five
minutes in length for any given instance.

Jeff Benfer Systems Administrator

卧槽,基础设施历史遗留问题,要重启。还不能自己来。这么坑。
好吧看来只能重启了。进服务器收拾收拾东西,发了个

Ok,you can restart it now,I’ve stopped the important services.

又是不到两分钟,服务器重启好了0.0 卧槽速度好快。完全没有感觉,检查了一下确实是重启了。
这时发现,private network还是不能用啊,ifconfig了一下。没有eth1。 ifup eth1 报错

Device eth1 does not seem to be present, delaying initialization.

哎哟卧槽看这情况是给我换了个虚拟网卡啊。
赶紧cat /etc/udev/rules.d/70-persistent-net.rules一发压压惊

# PCI device 0x1af4:0x1000 (virtio-pci)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="不给看", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"

# PCI device 0x1af4:0x1000 (virtio-pci)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="不给看", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

# PCI device 0x1af4:0x1000 (virtio-pci)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="不给看", ATTR{type}=="1", KERNEL=="eth*", NAME="eth2"

eth1和2都有是什么鬼,又发ticket问一下小哥,三分钟后小哥回复了

Hello,

eth2 should work for you. Please let us know if it does not.

Jeff Benfer Systems Administrator

那就把eth1的配置转移到eth2上试试吧。ifup eth2.顺利完成,互相ping了一下对面,终于通了。泪流满面

赶紧把必要的服务开启了一下,docker该开的也都开好了,MYSQL的主从同步检查了一下,还是连不上master啊

然而突然想到iptables的配置里写的3306端口只开放给eth1。赶紧去改了又show slave status\G一下。终于OK了。

然而说了这么多,除了分享网络配置和这RP不好遇到的奇葩问题以外,严重赞一下Vultr的ticket客服,凌晨两三点能在两分钟左右就回复我的ticket简直是业界良心,还能迅速解答我的问题。相比之下Digitalocean的10-20分钟略慢。国内的服务商就更不用说了。动辄一两天慢得要死不说,搞来搞去完全不专业。

最后的最后,放一下Vultr和Do的带Aff链接,虽然没人会用

Vultr
Digitalocean

DHL用自己的check digits规范把我坑了一下

这几天一直在搞条形码生成。因为有一个和DHL的合作项目要自动生成条形码打印出来。
而DHL给的条形码要求是interleaved 2of5.

查了一圈资料得知interleaved 2of5是没有check digits的
但是生成出来的条码很明显不对

后来在wikipedia发现A checksum can be added as last digit, which is calculated in the same way as UPC checksums.
于是用标准的checksums来计算check digit即

In the UPC-A system, the check digit is calculated as follows:

Add the digits in the odd-numbered positions (first, third, fifth,
etc.) together and multiply by three. Add the digits in the
even-numbered positions (second, fourth, sixth, etc.) to the result.
Find the result modulo 10 (i.e. the remainder when divided by 10… 10
goes into 58 5 times with 8 leftover). If the result is not zero,
subtract the result from ten.

但是生成出来的条码依旧和DHL给的范例不一样。反馈给DHL他们也说他们的机器扫描不成功。
后来以为是条码宽度问题。根据DHL给的要求把每条宽度设置为0.5mm到0.33mm之间。总宽度42mm
再次提交,DHL反馈说扫描出来了但是数字不对。首位多了0,末尾多了8.
万能的wikipedia又告诉我

Before the actual pairs there is a start code consisting of nnnn
(narrow bar-narrow space- narrow bar-narrow space), and after all
symbols there is the stop code consisting of Wnn (Wide bar-narrow
space-narrow bar).

Because digits are encoded by pairs, only an even number of digits can
be encoded. Typically an odd number of digits is encoded by adding a
"0" as first digit, but sometimes an odd number of digits is encoded
by using five narrow spaces in the last digit.

瞬间想到最后以为是不是barcode生成器自动给我添加的校验位。去查看了生成类的源代码发现

static public function compute($code, $crc, $type){
        if (! $crc) {
            if (strlen($code) % 2) $code = '0' . $code;
        } else {
            if ( ($type == 'int25') && (strlen($code) % 2 == 0) ) $code = '0' . $code;
            $odd = true;
            $sum = 0;
            for($i=strlen($code)-1; $i>-1; $i--){
                $v = intval($code[$i]);
                $sum += $odd ? 3 * $v : $v;
                $odd = ! $odd;
            }
            $code .= (string) ((10 - $sum % 10) % 10);
        }
        return($code);
    }

然而不传递checkdigit进去生成出来的依旧不对。
这时候想到DHL一开始发的Check digit calculation , Factor 4 and 9 see Specification。
wikipedia了一下。终于发现了

Identcode and Leitcode are variants of interleaved 2 of 5 with check
digits used by Deutsche Post.

一开始还不知道Deutsche Post是什么。查了一下 ,不就是DHL么。。。。
好坑啊。DHL还用自己的checkdigit规范。

果断去把生成类里的代码改成

$sum += $odd ? 4 * $v : 9 * $v;

又生成了一张。发现和DHL给的范例终于一模一样了。。

大功告成。
然而不知道为啥DHL用自己的checkdigit规范不用国际通用标准。真是好坑好坑。
另外,wikipedia真是个好东西。然而国内百度一下并没有任何资料。全都是卖东西的。