获取php pdo 执行的sql语句
class MyPDOStatement extends PDOStatement
{
protected $_debugValues = null;
protected function __construct()
{
// need this empty construct()!
}
public function execute($values=array())
{
$this->_debugValues = $values;
try {
$t = parent::execute($values);
// maybe do some logging here?
} catch (PDOException $e) {
// maybe do some logging here?
throw $e;
}
return $t;
}
public function _debugQuery($replaced=true)
{
$q = $this->queryString;
if (!$replaced) {
return $q;
}
return preg_replace_callback('/:([0-9a-z_]+)/i', array($this, '_debugReplace'), $q);
}
protected function _debugReplace($m)
{
$v = $this->_debugValues[$m[1]];
if ($v === null) {
return "NULL";
}
if (!is_numeric($v)) {
$v = str_replace("'", "''", $v);
}
return "'". $v ."'";
}
}
// have a look at http://www.php.net/manual/en/pdo.constants.php
$options = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_STATEMENT_CLASS => array('MyPDOStatement', array()),
);
// create PDO with custom PDOStatement class
$pdo = new PDO($dsn, $username, $password, $options);
// prepare a query
$query = $pdo->prepare("INSERT INTO mytable (column1, column2, column3)
VALUES (:col1, :col2, :col3)");
// execute the prepared statement
$query->execute(array(
'col1' => "hello world",
'col2' => 47.11,
'col3' => null,
));
// output the query and the query with values inserted
//http://stackoverflow.com/questions/7716785/get-last-executed-query-in-php-pdo
var_dump( $query->queryString, $query->_debugQuery() );
laravel Carbon
composer require nesbot/carbon
use Carbon\Carbon;
\Carbon\Carbon::setLocale('zh');
echo Carbon::now()->toDateTimeString();
echo Carbon::parse('2016-10-15')->toDateTimeString();
Carbon::parse('+3 days')->toDateTimeString();
echo Carbon::parse('next wednesday')->toDateTimeString();
echo Carbon::now()->modify('+15 days');
$first = Carbon::create(2012, 9, 5, 23, 26, 11);
$second = Carbon::create(2012, 9, 5, 20, 26, 11, 'America/Vancouver');
var_dump($first->gt($second)); // bool(false)
var_dump(Carbon::create(2012, 9, 5, 3)->between($first, $second)); // bool(true)
$dt = Carbon::now();
$dt->isWeekday();
echo Carbon::now()->subDays(5)->diffForHumans(); // 5天前
echo $dt->diffForHumans($dt->copy()->addMonth()); // 1月前
echo Carbon::now()->subDays(24)->diffForHumans(); // 3周前
PHP 二进制安全
//简单说就是传入的参数支持二进制数据,包括”\0″这种在 C 中表示字符串结束的字符
$string1 = "Hello";
$string2 = "Hello\x00Hello";
echo strcoll($string1, $string2); // 返回0, 由于是非二进制安全,误判为相等
echo strcmp($string1, $string2); // 返回负数
PHP 捕捉异常中断
class IndexController extends Controller
{
/**
* 脚本执行是否完成
* @var bool
*/
protected $complete = false;
public function __construct()
{
register_shutdown_function([$this, 'shutdown']);
}
/**
* 异常处理
*/
public function shutdown()
{
if ($this->complete === false) {
dump('log'); //此处应该输出日志并进行异常处理操作
}
}
}
PHP如何批量生成手机号
class Util {
private static $mobileSegment = [
'134', '135', '136', '137', '138', '139', '150', '151', '152', '157', '130', '131', '132', '155', '186', '133', '153', '189',
];
public function nextMobile()
{
$prefix = self::$mobileSegment[array_rand(self::$mobileSegment)];
$middle = mt_rand(2000, 9000);
$suffix = mt_rand(2000, 9000);
return $prefix . $middle . $suffix;
}
}
//匹配手机号的正则表达式 #^(13[0-9]|14[47]|15[0-35-9]|17[6-8]|18[0-9])([0-9]{8})$#
$arr = array(
130,131,132,133,134,135,136,137,138,139,
144,147,
150,151,152,153,155,156,157,158,159,
176,177,178,
180,181,182,183,184,185,186,187,188,189,
);
for($i = 0; $i < 10; $i++) {
$tmp[] = $arr[array_rand($arr)].' '.mt_rand(1000,9999).' '.mt_rand(1000,9999);
}
var_export(array_unique($tmp));
//输出
array (
0 => '139 9182 8973',
1 => '144 7038 6282',
2 => '182 2183 9323',
3 => '176 1226 2322',
4 => '183 1072 4890',
5 => '153 8744 2917',
6 => '152 1150 5508',
7 => '147 3404 5840',
8 => '139 3547 8652',
9 => '151 1968 2090',
)
global
$var1 = 1;
function test(){
global $var1;//global $var1;等于$var1=&$GLOBALS['var1'];
unset($var1);
}
test();
echo $var1;// 此处输出1
$var1 = 1;
function test(){
unset($GLOBALS['var1']);
}
test();
echo $var1;// 此处报错PHP Notice: Undefined variable: var1
sprintf截取小数
$str1 = 12.34;
$str2 = 12.35;
$str3 = 12.36;
echo sprintf('%.1f',$str1);//12.3
echo sprintf('%.1f',$str2);//12.3
echo sprintf('%.1f',$str3);//12.4
echo sprintf('%.1f', floor($str3));//12.3
echo sprintf('%.0f', 12.5); //12
echo sprintf('%.0f', 15.5); //16
php递归无限分类
$pdo = new PDO("mysql:host=localhost;dbname=test", "root", "root");
function getCategories(PDO $pdo, $pid = 0)
{
$sql = 'SELECT * FROM `category` WHERE pid=:pid';
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':pid', $pid, PDO::PARAM_INT);
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($data as &$row) {
$row['subs'] = getCategories($pdo, $row['id']);
}
return $data;
}
$a = getCategories($pdo);
print_r($a);
递归
public function find_children_cat($cat_id, $data)
{
static $tem=array();
foreach ($data as $val)
{
if ( $val['parent_id'] == $cat_id )
{
array_push($tem, $val['cat_id']);
$this->find_children_cat($val['cat_id'], $data);
}
}
return $tem;
}
HTTP Basic Authorization
//请求的时候添加 Authorization头,值为"Basic "+base64_encode(username+':'+password)
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "[$username]:[$password]");
switch全等判断
switch($value){
case null: echo 'null';
break;
case '': echo '空';
break;
}
当$value = ''时,switch会进入第一个case
switch(true) {
case null === $value : echo 'null';
break;
case '' === $value: echo '空';
break;
}
/**
* 移除字符串的BOM
*
* @param string $str 输入字符串
* @return string 输出字符串
*/
function removeBOM($str)
{
$str_2 = substr($str, 0, 2);
$str_3 = substr($str, 0, 3);//$str_2.$str{2};
$str_4 = substr($str, 0, 4);//$str_3.$str{3};
if ($str_3 == pack('CCC',0xef,0xbb,0xbf)) //utf-8
return substr($str, 3);
elseif ($str_2 == pack('CC',0xfe,0xff) || $str_2 == pack('CC',0xff,0xfe)) //unicode
return substr($str, 2);
elseif ($str_4 == pack('CCCC',0x00,0x00,0xfe,0xff) || $str_4 == pack('CCCC',0xff,0xfe,0x00,0x00)) //utf-32
return substr($str, 4);
return $str;
}
数组重新组合
$arr1 = [
['tracking1','[email protected]','80'],
['tracking1','[email protected]','50'],
['tracking2','[email protected]','60'],
['tracking2','[email protected]','30'],
];
$arr2 = [];
foreach ($arr1 as $data) {
list($account,$mail,$val) = $data;
isset($arr2[$account.$mail]) || $arr2[$account.$mail]=[$account,$mail,[]];
array_push($arr2[$account.$mail][2],$val);
}
$arr2 = array_values($arr2);
var_dump($arr2);
$arr = [['tracking1','[email protected]','80'],
['tracking1','[email protected]','50'],
['tracking2','[email protected]','60'],
['tracking2','[email protected]','30']];
$finalArr = [[[]]];
$mailArr =[];
foreach ($arr as $k=>$v){
$mailKey = array_search($v[1],$mailArr);
if($mailKey!==false){
array_push($finalArr[$mailKey][2],$v[2]);
}else{
$finalArr[$k] = $v;
$finalArr[$k][2] = [$v[2]];
$mailArr[$k]=$v[1];
}
}
$finalArr = array_values($finalArr);
var_dump($finalArr);
preg_replace_callback
$items = [
'a > 1',
'b > 0',
'abc' => 'c > 1'
];
$subject = '#0 and #1 or (#0) and #abc #nooo';
echo preg_replace_callback('/#([a-z0-9_]+)/i', function($v) use ($items){
return isset($items[$v[1]]) ? $items[$v[1]] : $v[0];
}, $subject);//a > 1 and b > 0 or (a > 1) and c > 1 #nooo
用json保存二进制数
$data = ['a1' => sprintf('0b%06b', 0b000100)]; // 转成JSON后: {"a1": "0b000100"}
保留1位小数,不四舍五入,为整数时补0
echo sprintf('%.1f', floor($str));
sprintf('%.1f',12.35);//12.3
sprintf('%.1f',12.36);//12.4
number_format(12.35,1,'.','')//12.4
number_format(12.36,1,'.','')//12.4
json_decode 后,数字对象转换成了 科学计数法
$obj='{"order_id":213477815351175,"buyer":100001169269154}';
$obj=$this->json_decode($obj,TRUE);
print_r($obj);
Array
(
[order_id] => 2.1347781535118E+14
[buyer] => 1.0000116926915E+14
)
$obj='{"order_id":213477815351175,"buyer":100001169269154}';
$obj=$this->json_decode($obj,TRUE);
foreach ($obj as $key=>$val){
$obj[$key]=number_format($val,0,'','');
}
print_r($obj);
Array
(
[order_id] => 213477815351175
[buyer] => 100001169269154
)
从指定数字中获取随机组合的方法
//http://blog.csdn.net/fdipzone/article/details/51794055
function getNumGroups($var, $num){
// 数量不正确
if($var<$num){
return array();
}
$total = 0;
$result = array();
for($i=1; $i<$num; $i++){
$tmp = mt_rand(1, $var-($num-$i)-$total);
$total += $tmp;
$result[] = $tmp;
}
$result[] = $var-$total;
return $result;
}
$result = getNumGroups(100, 3);
print_r($result);
Array
(
[0] => 42
[1] => 25
[2] => 33
)
crontab 精确到执行分钟内某一秒执行的方法
test.php
echo date('Y-m-d H:i:s').PHP_EOL;
* * * * * php /Users/fdipzone/test.php >> /Users/fdipzone/test.log
* * * * * sleep 30; php /Users/fdipzone/test.php >> /Users/fdipzone/test.log
callable强制指定回调类型
function dosth($callback){
call_user_func($callback);
}
function callback(){
echo 'do sth callback';
}
dosth('callback');
function dosth(callable $callback){
call_user_func($callback);
}
dosth('abc');//提示错误:TypeError: Argument 1 passed to dosth() must be callable
lcg_value与mt_rand生成0~1随机小数的效果比较
/**
* 生成0~1随机小数http://blog.csdn.net/fdipzone/article/details/52829930
* @param Int $min
* @param Int $max
* @return Float
*/
function randFloat($min=0, $max=1){
return $min + mt_rand()/mt_getrandmax() * ($max-$min);
}
// 获取microtime
function get_microtime(){
list($usec, $sec) = explode(' ', microtime());
return (float)$usec + (float)$sec;
}
lcg_value();
//lcg_value()执行速度快,但随机效果不及基于mt_rand()与mt_getrandmax()算法实现
header('content-type: image/png');
$im = imagecreatetruecolor(512, 512);
$color1 = imagecolorallocate($im, 255, 255, 255);
$color2 = imagecolorallocate($im, 0, 0, 0);
for($y=0; $y<512; $y++){
for($x=0; $x<512; $x++){
$rand = randFloat();
if(round($rand,2)>=0.5){
imagesetpixel($im, $x, $y, $color1);
}else{
imagesetpixel($im, $x, $y, $color2);
}
}
}
imagepng($im);
imagedestroy($im);
/**
* 检查连接是否可用
* @param Link $dbconn 数据库连接
* @return Boolean
*/
function pdo_ping($dbconn){
try{
$dbconn->getAttribute(PDO::ATTR_SERVER_INFO);
} catch (PDOException $e) {
if(strpos($e->getMessage(), 'MySQL server has gone away')!==false){
return false;
}
}
return true;
}
Maximum function nesting level of '100' reached, aborting! in
function test() {
echo count(debug_backtrace()) . "\n";
}
function test2() {
test();
}
test(); //输出1
test2(); //输出2
惰加载 只是给$this->['config']一个匿名函数,当你要用到的时候,才会进行new Config($config)的操作
public function __construct($config)
{
parent::__construct();
$this['config'] = function () use ($config) {
return new Config($config);
};
laravel验证两个字段必须有一个必填
'email' => 'required_without:phone',
'phone' => 'required_without:email',
set_time_limit 可以控制秒级的最大执行时间,一个500毫秒的超时
declare(ticks=1);
$start = microtime(true);
register_tick_function(function () use ($start) {
(microtime(true) - $start < 0.5) or die("timeout\n");
});
function a() {
echo "do some work\n";
usleep(600000);
echo "do another work\n";
}
a();
利用cookie模拟登陆
//设置post的数据
$post = array (
'email' => '账户',
'pwd' => '密码'
);
//登录地址
$url = "登陆地址";
//设置cookie保存路径
$cookie = dirname(__FILE__) . '/cookie.txt';
//登录后要获取信息的地址
$url2 = "登陆后要获取信息的地址";
//模拟登录
login_post($url, $cookie, $post);
//获取登录页的信息
$content = get_content($url2, $cookie);
//删除cookie文件
@ unlink($cookie);
var_dump($content);
//模拟登录
function login_post($url, $cookie, $post) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post));
curl_exec($curl);
curl_close($curl);
}
//登录成功后获取数据
function get_content($url, $cookie) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
$rs = curl_exec($ch);
curl_close($ch);
return $rs;
}
php self
class Base {
public function log() {
// 目标类,输出:A/C
echo static::class;
// 基类,输出:Base
//echo __CLASS__;
echo self::class;
}
}
class A extends Base {
public function log1() {
echo self::class;
}
}
class C extends A {
public function log2() {
echo self::class;
}
}
//self 指向基类 Fruit,也就是 __CLASS__ 的类
//static、$this 指向最终new的类 Apple
$a = new A();$c = new C();
$a->log(); //输出 A Base
$c->log(); //输出 C Base
$c->log1(); //输出 A
$c->log2(); //输出 C
mysql session cookie
CREATE TABLE sessions (
user_id int(10) unsigned NOT NULL,
session text NOT NULL,
md5 char(32) NOT NULL,
PRIMARY KEY (user_id)
) ENGINE=MEMORY DEFAULT CHARSET=utf8;
其中:
user_id存储的是用户ID,作为主键.
session存储的是用户的会话数组经过serialize或json_encode后的字符串.
md5存储的是session字段的MD5值,用于实现Check And Set版本号乐观锁:
--读取会话
SELECT session, md5 --写入会话时需要用到这里查出来的md5,就是下面的$last_md5
FROM sessions WHERE user_id = $user_id
--写入会话
UPDATE sessions
SET session = $str, md5 = md5($str)
WHERE user_id = $user_id
AND md5 = $last_md5 --检查MD5,确保session字段没有被修改过