标签归档:PHP基础

PHP 坑之 ==

PHP 中 “== ”判断两个变量是否相等的时候会进行自动的类型转换。今天Tom Hessman,在twitter上提到了PHP用==做判断的时候一种极端情况(很坑)。

1
2
3
4
5
6
//ok it return true
var_dump(md5('240610708') == md5('QNKCDZO'));
var_dump(md5('240610708'));
//string(32) "0e462097431906509019562988736854"
var_dump(md5('QNKCDZO'));
string(32) "0e830400451993494058024219903391"

PHP把两个字符串转换成科学计数来比较了。。。

严谨比较还是用 === 这个吧

PHP 中mysql_ping 函数小坑

官方文档是这样介绍的:

mysql_ping() 检查到服务器的连接是否正常。如果断开,则自动尝试连接。本函数可用于空闲很久的脚本来检查服务器是否关闭了连接,如果有必要则重新连接上。如果到服务器的连接可用则 mysql_ping() 返回 TRUE,否则返回 FALSE。

看一眼可能会以为mysql_ping 就两个返回值(TRUE | FALSE),但是实际情况是还有第三个返回值。这个问题官方文档下方是有人评论的,而且是在七年前:(

1
2
3
4
5
6
//When checking if a $resource works...
//be prepared that mysql_ping returns NULL as long as $resource is no correct mysql resource.
$resource =NULL;
var_dump = @mysql_ping($resource);
# showing NULL
//This could be used to decide of a current $resource is a mysql or a mysqli connection when //nothing else is available to do that...

越来越觉着PHP是个玩具型的东西。。。

proc_open使用一例

平时工作中很少用到proc_open这个函数,最近用这个函数做了一个数据库管理小程序。

实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//file name db.php
$mysql_list = array(
    'test' => 'mysql -hlocalhost -utest -p123456 -P3306 test',
    'test2' => 'mysql -h172.16.190.199 -utest2 -p654321 -P3306 test2',
);
$desc = array(
    0 => STDIN,
    1 => STDOUT,
    2 => STDERR,
);
$flag = @$argv[1];
$env = $_ENV;
$cwd = getcwd();
if(!isset($mysql_list[$flag]))
{
    exit("can not found the $flag");
}
$re = proc_open($cmd, $desc, $pipes, $cwd, $env);
if(!$re)
{
    exit('failed to execute cmd');
}

这样有很多数据库需要管理的时候就比较容易了,直接配置下连接参数,然后:

php db.php test

简单实用吧~

补一个bash实现的。

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
flag=$1;
case $flag in
  'test')
      (mysql -hlocalhost -utest -p123456 -P3306 test);
      ;;
  'test2')
      (mysql -h172.16.190.199 -utest2 -p654321 -P3306 test2);
      ;;
   *)
      echo 'can not found the flag cmd';
      ;;
esac;

PHP 中的取余数操作

这个细节一直没有注意,今天补上。

一般我们取余操作都是直接用”%”这个操作符来完成,但是这个操作符受到运行环境的限制,被余数不能超过PHP_INT_MAX,所以官方提供了bcmod这个函数来对任意数进行取余数操作。

运行下面的代码,可以看到效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
 * 这个在官方评论中找到的一个对任意数取余的函数实现(看了下是10年写下的)
 * my_bcmod - get modulus (substitute for bcmod)
 * string my_bcmod ( string left_operand, int modulus )
 * left_operand can be really big, but be carefull with modulus :(
 * by Andrius Baranauskas and Laurynas Butkus :) Vilnius, Lithuania
 **/

function my_bcmod( $x, $y )
{
    // how many numbers to take at once? carefull not to exceed (int)
    $take = 5;    
    $mod = '';

    do
    {
        $a = (int)$mod.substr( $x, 0, $take );
        $x = substr( $x, $take );
        $mod = $a % $y;    
    }
    while ( strlen($x) );

    return (int)$mod;
}

// example
$a =  "7044060001970316212900";
$b = 150;
echo my_bcmod($a, $b ).PHP_EOL;
echo bcmod($a, $b).PHP_EOL;
echo $a % $b;

This XML document is invalid 错误处理

在做XML解析的时候很可能遇到This XML document is invalid这种错误。

在PHP中根据使用的解析函数(字符串编码为UTF-8)不同可能的提示有以下两种:

1)xml_parser*函数错误提示

This XML document is invalid, likely due to invalid characters. XML error: Invalid character at line 30, column 25

2)XMLReader类 或 simplexml_load*函数

error on line 30 at column 25: Input is not proper UTF-8, indicate encoding !
Bytes: 0x1D 0xE7 0xBB 0x

搜索了好久没有找到完美的解决方案,最后分析发现出现这种问题一般是因为出现了不可见字符。于是就试了试能不能通过去除不可见字符的方式来绕过这个错误提示,从而使解析继续下去。经过实验在我的测试中是可以的,所以分享出来,希望对遇到同样问题的朋友能节约一些时间。

可以通过如下方式去除字符串中的不可见字符。

preg_replace(‘/[^\P{C}\n]+/u’, ”, $utf8_data)