邢栋博客

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

php之XMLReader简单事例

新建xml.xml

<?xml version="1.0" encoding="utf-8"?>  
<shows>  
    <show>  
        <name>action</name>
        <age>18</age>
        <sex>男</sex>
    </show>  
    <show>  
        <name>yiyi</name>
        <age>20</age>
        <sex>女</sex>
    </show>  
</shows>  
xml.php如下
<?php
    $items = [];
    $reader = new XMLReader();
    $reader->open('xml.xml','utf-8');

    while($reader->read()){
        if($reader->name == 'show' && $reader->nodeType == XMLReader::ELEMENT){
            $item = [];
            while($reader->read() && $reader->name != 'show'){
                if($reader->nodeType != XMLReader::ELEMENT)continue;

                $name = $reader->name;
                $value = $reader->readString();
                $item[$name]  = $value;
            }
            $items[] = $item;

        }

    }
    echo "<pre>";
    print_r($items);


文本文件和二进制文件相关以及php操作二进制文件
文本文件和二进制文件有什么不同

1.文本文件是基于字符编码的文件
2.除了文本文件以外的文件成为二进制文件
3.二进制文件编码是变长的,灵活利用率高
4.两者读写差别仅体现在回车换行符的处理上
5.文本文件是一种特殊的二进制文件


php写入和读取二进制文件 简单事例

//写入方式1
// $fh = fopen('my.db','w'); 
// $name  = pack('A20','zsf');//长度不足20会以空格补充
// $age = pack('S',1);
// $email = pack('a20','xingdong365@qq.com');//长度不足20会以null补充

// fwrite($fh,$name.$age.$email);

//写入方式2,同上
$fh = fopen('my_1.db','w');
$data = pack('A20Sa20','zsf',1,'xingdong365@qq.com');
fwrite($fh,$data);


$tmp = file_get_contents('my_1.db');
$data = unpack('A20name/Sage/a20email',$tmp);


print_r($data);


文件指针的定位操作

fseek() 在文件指针中定位
ftell() 返回文件指针读/写的位置
rewind() 返回文件指针的位置
feof() 测试文件指针是否达到了文件结束的位置

php的几个人坑人小题
<?php
	//----example 1
	$a = 3;
	$b =5;
	if($a = 5 || $b = 7){
		++$a;
		$b++;
	}
	echo $a,'--'.$b,"<br>"; //输出结果 为 1--6
	//说明
	// $a = 5 || $b =7 ,执行逻辑为 $a = (5||$b=7),$a = true,布尔型值++ 一直为1	

	//----example 2
	$count = 5;
	function get_count(){
		static $count = 0;
		return $count++;
	}
	++$count;  //此时$count为6
	get_count(); //函数里 返回的是 0, static $count 变成 1
	echo get_count(),"<br>";//输出结果为1 

	//----example 3
	echo count('567')+count(null)+count(false),"<br>"; //返回2 ,count(null)为0,其余的为1

	//----example 4
	$a = 0.2+0.7;
	$b = 0.9;
	var_dump($a == $b);//返回 false


PHP trait 学习笔记
自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait。
Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method。Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。
Trait 和 Class 相似,但仅仅旨在用细粒度和一致的方式来组合功能。 无法通过 trait 自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用的几个 Class 之间不需要继承。

example 1

<?php
trait Dog{
	public $name="dog";
	public function bark(){
	   echo "This is dog <br/>";
	}
}
class Animal{
	public function eat(){
		echo "This is animal eat<br/>";
	}
}
class Cat extends Animal{
	use Dog;
	public function drive(){
		echo "This is cat drive<br/>";
	}
}
$cat = new Cat();
$cat->drive();
$cat->eat();
$cat->bark();

//输出结果如下:
//This is cat drive
//This is animal eat
//This is dog 



example 2
从基类继承的成员会被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法。
从基类继承的成员被插入的 SayWorld Trait 中的 MyHelloWorld 方法所覆盖。其行为 MyHelloWorld 类中定义的方法一致。优先顺序是当前类中的方法会覆盖 trait 方法,而 trait 方法又覆盖了基类中的方法。

<?php
class Base {
	public function sayHello() {
		echo 'Hello ';
	}
}

trait SayWorld {
	public function sayHello() {
		parent::sayHello();
		echo 'World!<br>';
	}
}
class MyHelloWorld extends Base {
	use SayWorld;
}

$o = new MyHelloWorld();
$o->sayHello();

//输出结果为  Hello World!

example 3 冲突的解决

如果两个 trait 都插入了一个同名的方法,如果没有明确解决冲突将会产生一个致命错误。

为了解决多个 trait 在同一个类中的命名冲突,需要使用 insteadof 操作符来明确指定使用冲突方法中的哪一个。

以上方式仅允许排除掉其它方法,as 操作符可以 为某个方法引入别名。 注意,as 操作符不会对方法进行重命名,也不会影响其方法。

在本例中 Talker 使用了 trait A 和 B。由于 A 和 B 有冲突的方法,其定义了使用 trait B 中的 smallTalk 以及 trait A 中的 bigTalk。

Aliased_Talker 使用了 as 操作符来定义了 talk 来作为 B 的 bigTalk 的别名。
<?php
trait A {
	public function smallTalk() {
		echo 'a';
	}
	public function bigTalk() {
		echo 'A';
	}
}

trait B {
	public function smallTalk() {
		echo 'b';
	}
	public function bigTalk() {
		echo 'B';
	}
}

class Talker {
	use A, B {
		B::smallTalk insteadof A;
		A::bigTalk insteadof B;
	}
}

class Aliased_Talker {
	use A, B {
		B::smallTalk insteadof A;
		A::bigTalk insteadof B;
		B::bigTalk as talk;
	}
}


(new Talker)->smallTalk(); //输出 b
(new Talker)->bigTalk(); ////输出 A
(new Aliased_Talker)->smallTalk();//输出 b
(new Aliased_Talker)->bigTalk();//输出 A
(new Aliased_Talker)->talk();//输出 B
example4 修改方法的访问控制
使用 as 语法还可以用来调整方法的访问控制。
trait HelloWorld {
	public function sayHello() {
		echo 'Hello World!';
	}
}

// 修改 sayHello 的访问控制
class MyClass1 {
	use HelloWorld { sayHello as protected; }
}

// 给方法一个改变了访问控制的别名
// 原版 sayHello 的访问控制则没有发生变化
class MyClass2 {
	use HelloWorld { sayHello as private myPrivateHello; }
}

php 用 ... 定义变长参数函数
       // 1.
	$email = [];
	$email[] = 'hello world !';
	$email[] = 'what are you doing?';
	//mail('my@126.com',...$email);


	//2
	function addAll(...$num){
		return array_sum($num);
	}

	echo addAll(1,2,3,4,5,6,7,8,9);
php 的 yield 简单使用
    // 文件的读取(一)
    function getLines($filename){
        $f = fopen($filename,'rb');
        try{
            while ($line = fgets($f)) {
                yield $line;
            }
        }finally{
            fclose($f);
        }
    }
    $lines = getLines('my.log');
    foreach($lines as $line){
        echo $line.PHP_EOL;
    }

    // 文件的读取(二)
    function getLiness($filename){
        $f = fopen($filename,'rb');
        try{
            while ($line = fgets($f)) {
                $lineParts = explode(' ',$line,2);
                yield $lineParts[0] => $lineParts[1];
            }
        }finally{
            fclose($f);
        }
    }

    foreach(getLiness('my.log') as $ip => $line){
        echo $ip.'=》'.$line.PHP_EOL;
    }


    // 大数组的构建
    function xrange($start,$end,$step=1){
        for ($i=$start; $i <= $end; $i+=$step) {
            yield $i;
        }
    }
    foreach (xrange(1,999) as $num) {
        echo $num,"\n";
    }
php安装vld扩展查看编译opcode

php安装vld扩展查看编译opcode

wget http://pecl.php.net/get/vld-0.14.0.tgz

tar -zxvf vld-0.14.0.tgz 

/usr/local/php/bin/phpize 

./configure --with-php-config=/usr/local/php/bin/php-config --enable-vld

make && make install 

vim /usr/local/php/etc/php.ini ,在文件最后面加入 extension=vld.so

service php-fpm restart //重启php-fpm


例子 

vim array.php
<?php
        $tmp = array('a'=>'a','b'=>'b','c'=>'c');
        $a = $tmp['a'];
        $b = $tmp[b];
        $c = $tmp["c"];


然后执行 
php -dvld.active=1 ./array.php    //如果加入 -dvld.execute=0(默认是1),则文件只输出opcode而不执行

返回结果如下
Finding entry points
Branch analysis from position: 0
Jump found. (Code = 62) Position 1 = -2
filename:       /data/www/study/array.php
function name:  (null)
number of ops:  9
compiled vars:  !0 = $tmp, !1 = $a, !2 = $b, !3 = $c
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   ASSIGN                                                   !0, <array>
   3     1        FETCH_DIM_R                                      $5      !0, 'a'
         2        ASSIGN                                                   !1, $5
   4     3        FETCH_CONSTANT                                   ~7      'b'
         4        FETCH_DIM_R                                      $8      !0, ~7
         5        ASSIGN                                                   !2, $8
   5     6        FETCH_DIM_R                                      $10     !0, 'c'
         7        ASSIGN                                                   !3, $10
   6     8      > RETURN                                                   1

branch: #  0; line:     2-    6; sop:     0; eop:     8; out1:  -2
path #1: 0, 
PHP Notice:  Use of undefined constant b - assumed 'b' in /data/www/study/array.php on line 4	

可以看到$tmp[b] 在编译成opcode的时候就比其他两个多一步



php正则相关知识点笔记

正则 环视(零宽断言)

环视不匹配任何字符,只匹配文本中的特定位置。类似于\b,^,$那样。环视不会占用字符。

环视分为顺序和逆序两种。

顺序
(?=exp)位置的后面能匹配exp。例如(?=\d)当前位置右边是数字
(?!exp)位置的后面不能匹配exp。例如(?!\d)当前位置右边不是数字

逆序
(?<=exp)位置的前面能匹配exp。例如(?<=\d)当前位置左边是数字
(?<!exp)位置的前面不能匹配exp。例如(?<!\d)当前位置左边不是数字


(?=jeffrey)jeff 等价于  jeff(?rey)

例子
<?php
$string = '5345678986';
$pattern = '/(?!=\d)(?=(\d{3})+$)/';
$replacement  = ',';
echo  preg_replace($pattern, $replacement, $string);//5,345,678,986


贪婪与懒惰
贪婪 通常的行为是匹配尽可能多的字符
a.*b -- aabab -- 会匹配 aabab
懒惰 只要在后面加上一个问号?。这样.*? 就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。
a.*?b --- aabab  --  会匹配 aab和 ab


正则的引擎
是否支持忽略优先量词和分组捕获
支持的话是 NFA
不支持的话是 DFA

DFA文本主导   //  awk,egrep,flex,lex,msyql,procmail
NFA表达式主导 //  gnu,emacs,java,ergp,less,more,.net,perl,php,python,ruby,sed,vi



php pcre的主要函数

preg_grep    --------------  返回匹配模式的数组条目
preg_match --------------   执行一个正则表达式匹配
preg_match_all -------------- 执行一个全局正则表达式匹配
preg_filter --------------  执行一个正则表达式搜索和替换
preg_replace --------------   执行一个正则表达式的搜索和替换
preg_replace_callback --------------执行搜索并且使用一个回调进行替换
preg_split-------------- 通过一个正则表达式分隔字符串
preg_quote -------------- 转义正则表达式字符
preg_last_error-------------- 返回最后一个pcre正则执行产生的错误代码



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