邢栋博客
邢栋博客,Action博客,记录工作和生活中的点点滴滴
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
php代码的执行过程
扫描->解析->编译->执行->输出
1.扫描(scanning) 将index.php内容变成一个个语言片段(token)
扫描->解析->编译->执行->输出
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) 将要输出的内容输出到缓冲区
关于shell函数的简单总结说明
标签:
shell
shell函数说明
1.函数调用时,脚本的位置函数($* $@ $# $1...)会被替换为函数的参数,函数执行完毕后,会恢复原值
2.函数中的变量默认为全局作用域,除非使用local关键字定义
3.通过return 命令可以让函数返回数字值,常用于表示函数执行是否成功。如果返回字符串值,则需要在函数中使用echo,然后再在函数外使用$()捕获;或者将字符串存在一个变量中,函数执行完毕后读取该变量
4.如果函数中没有使用 return 指定返回值,则函数返回值为最后一条命令的退出码($?捕获返回值)
1.函数调用时,脚本的位置函数($* $@ $# $1...)会被替换为函数的参数,函数执行完毕后,会恢复原值
2.函数中的变量默认为全局作用域,除非使用local关键字定义
3.通过return 命令可以让函数返回数字值,常用于表示函数执行是否成功。如果返回字符串值,则需要在函数中使用echo,然后再在函数外使用$()捕获;或者将字符串存在一个变量中,函数执行完毕后读取该变量
4.如果函数中没有使用 return 指定返回值,则函数返回值为最后一条命令的退出码($?捕获返回值)
5.简单事例
#!/bin/bash foo() { echo "is your name $* ?" while true do echo -n "enter yes or no:" read x case $x in y|yes) return 0;; n|no) return 1;; *) echo "answer yes or no" esac done } echo "your parameters is $*" if foo "$1" then echo "hi $1,nice name" else echo "never mind" fi exit 0
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.文本文件是一种特殊的二进制文件
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
<?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 3 冲突的解决
如果两个 trait 都插入了一个同名的方法,如果没有明确解决冲突将会产生一个致命错误。
为了解决多个 trait 在同一个类中的命名冲突,需要使用 insteadof 操作符来明确指定使用冲突方法中的哪一个。
以上方式仅允许排除掉其它方法,as 操作符可以 为某个方法引入别名。 注意,as 操作符不会对方法进行重命名,也不会影响其方法。
在本例中 Talker 使用了 trait A 和 B。由于 A 和 B 有冲突的方法,其定义了使用 trait B 中的 smallTalk 以及 trait A 中的 bigTalk。
Aliased_Talker 使用了 as 操作符来定义了 talk 来作为 B 的 bigTalk 的别名。
使用 as 语法还可以用来调整方法的访问控制。
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();//输出 Bexample4 修改方法的访问控制
使用 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; } }