1.判斷對象類型
if ($object instanceof stdClass) {
echo 'yes';
}
還有類似的函數
is_object
is_array
stdClass類是PHP的一個內部保留類,初始時沒有成員變量也沒成員方法,所有的魔術方法都被設置爲NULL,可以使用其傳遞變量參數,但是沒有可以調用的方法。stdClass類可以被繼承,只是這樣做沒有什麼意義。2.安裝php的加密模塊mcrypt
sudo rpm -ivh http://mirrors.sohu.com/fedora-epel/6/i386/epel-release-6-7.noarch.rpm
yum install php-mcrypt
sudo yum install php-mcrypt -y
php.ini添加
extension=mcrypt.so
3.跨域名的瀏覽,cookie是不能傳遞的,貌似可以用sso之類的東東實現,有空研究一下
4.php的int在32bit和64bit機器上能表示的最大整數不一樣,前者最大2^31-1,超過就自動變成float,如果超過還強制成int就會溢出
32bit機器測試:
$idarray = explode(',', $ids);
foreach ($idarray as $index=>$value)
$idarray[$index] = (int)$value;
var_dump(2147483647);
var_dump(2147483650);
var_dump((int)2147483650);
var_dump($ids);
var_dump($idarray);die();
output:int(2147483647) float(2147483650) int(-2147483646) string(10) "2789214350" array(1) { [0]=> int(2147483647) }
64bit機器測試:[dongsong@localhost 230_proc]$ php -r "var_dump(2147483647);var_dump(2147483650);"
int(2147483647)
int(2147483650)
官方文檔的說明:http://www.php.net/manual/zh/language.types.integer.php5.==和===的區別:==會在把兩個值自動轉換成同類型後再比較,而===在比較前不轉換
6.溫故而知新
7.無敵大坑(讓我對PHP無盡反感,連個單步跟蹤都沒有,排查錯誤麻煩得好死):include/require(_once)的時候如果是在函數內部執行的,那麼被引入的文件(a.php)的代碼就會添加在函數內部這個位置,那麼a.php中的定義的全局變量會變成局部變量,如果a.php中的某個函數對a.php中的全局變量做了global引入,這個函數在執行時會發現global引入的全局變量都是null。所以一般php文件引入最好放在文件開頭(當然,這樣也可能存在一個問題,那就是污染全局變量數組,自己權衡吧)
8.打開所有錯誤報告
error_reporting(E_ALL);
錯誤直接輸出而不是寫入日誌文件
ini_set("display_errors", true);
顯示php的所有配置
php -i
9.print_r($myObj,true) 不輸出到屏幕而是作爲返回值
10.對一個對php有牴觸情緒的人來說,這個絕對是天坑(2014.1.24):
數組的數字化string key會自動變成int key,如果數字化string key超出32位機器php表示的int最大值(見本章item4)就會保留string key不變(今天做程序移植,老機器是32位,新機器是64位,所以踩坑裏了),http://stackoverflow.com/questions/4100488/a-numeric-string-as-array-key-in-php
如果上述還不夠坑的,那麼再來看看array_shift(),將array的第一個單元移出並作爲結果返回,將array的長度減一併將所有其他單元向前移動一位。所有的數字鍵名改爲從零開始計數,文字鍵名將不變。(我今天遇到的BUG就是這兩種的疊加,事實證明,不要讓不懂技術的老闆去買人家的軟件產品,最終受苦的還是我們碼農)
[dongsong@localhost php_study]$ cat array_key.php
<?php
$testkeys = array("3661516534025750", (float)3661516534025750);
foreach($testkeys as $key) {
echo "\nto test key : ";
var_dump($key);
$myarray = array();
$myarray[$key] = 'hello,world';
var_dump($myarray);
}
$myarray = array("3661516534025750"=>"hello", "3661516534025760"=>"world");
echo "\nto test array_shift :\n";
var_dump($myarray);
array_shift($myarray);
var_dump($myarray);
[dongsong@localhost php_study]$ php array_key.php
to test key : string(16) "3661516534025750"
array(1) {
[3661516534025750]=>
string(11) "hello,world"
}
to test key : float(3.6615165340258E+15)
array(1) {
[3661516534025750]=>
string(11) "hello,world"
}
to test array_shift :
array(2) {
[3661516534025750]=>
string(5) "hello"
[3661516534025760]=>
string(5) "world"
}
array(1) {
[0]=>
string(5) "world"
}
[dongsong@localhost php_study]$ file /sbin/init
/sbin/init: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
11.php mysql_connect()的問題:同一個進程用一樣的參數調用該函數其實沒有建立新的連接,如果函數內部建立了連接然後關閉連接,函數外面已有連接就失效了
http://no1.php.net/manual/zh/function.mysql-connect.php
參數new_link可以解決這個問題:如果用同樣的參數第二次調用 mysql_connect(),將不會建立新連接,而將返回已經打開的連接標識。參數 new_link 改變此行爲並使 mysql_connect() 總是打開新的連接,甚至當 mysql_connect() 曾在前面被用同樣的參數調用過。
12.file_put_contents('/tmp/xds', print_r($data,true), FILE_APPEND|LOCK_EX);
var_dump($t);die();
不解釋。
13.<2014.11.29> tbl_vouch_log.orderId, php入庫時用的是orderid,入庫成功。排查這個原因。轉了一圈才知道mysql的列名和索引名是大小寫不敏感的。
知識點:
1>php程序被httpserver執行時我們看不到看不到自己添加到stdout/stderr的調試信息,這時候用file_put_contents(filename, print_r(varname,true), FILE_APPEND| LOCK_EX )。這是大家經常用的方式。
更簡單的方式如下(參見http://us2.php.net/manual/en/book.outcontrol.php):
ob_start(); //入口處
//各種往stdout寫的調試輸出
file_put_contents(filename, print_r(ob_get_clean(), true), FILE_APPEND| LOCK_EX); //清理所有輸出並寫入文件,只用一次即可。
2>打開mysql常規查詢的日誌來跟蹤sql(4.1沒權限看mysql用戶寫的文件)
set global general_log = ON;
set global general_log_file ='/tmp/xds';
3>我們GMT的php框架用的是php的PDO來做數據庫操作,要打印最終的sql語句可以用debugDumpParams(參見http://us2.php.net/manual/en/pdostatement.debugdumpparams.php):
ob_start();
$query = "INSERT INTO `$tableName`($colName) VALUES($colValue)";
$statement = $this->pdo->prepare($query);
$statement->execute();
$statement->debugDumpParams();
file_put_contents('/tmp/xds', print_r(ob_get_clean(), true), FILE_APPEND);
4>mysql配置大小寫敏感的選項
lower_case_file_system(http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_lower_case_file_system)
mysql定位數據目錄時需要用這個選項,只讀變量,不能在mysql運行期修改
OFF 文件名大小寫敏感
ON 文件名大小寫不敏感
lower_case_table_names
0 表名按照指定的名字存儲,比較時大小寫敏感(在wins等大小寫不敏感的系統上做這個設置沒用;wins默認1,mac默認2)
1 表名按照小寫名存儲,比較時忽略大小寫
2 表名按照指定的名字存儲,但用小寫名做比較
用innodb表時,在所有平臺都應配置爲1
列名和索引名在任何平臺都是大小寫不敏感的(http://dev.mysql.com/doc/refman/5.7/en/identifier-case-sensitivity.html),觸發器是大小寫敏感(who care)
http://dev.mysql.com/doc/refman/5.1/en/identifier-case-sensitivity.html
14.數數PHP裏面的那些坑(PS:這麼說並不是我中招了,中這種招是幾個PHP初學同事了。對於PHP變量生命期、array和stdClass的自動創建規則有了解的話就沒什麼奇怪的了。)
[dongsong@localhost php-study]$ cat localtest.php
<?php
for($i = 1; $i < 3; $i++) {
$att[] = $i*10;
var_dump($att);
}
[dongsong@localhost php-study]$ php localtest.php
array(1) {
[0]=>
int(10)
}
array(2) {
[0]=>
int(10)
[1]=>
int(20)
}
[dongsong@localhost php-study]$ cat stdobj_test.php
<?php
for($i=1; $i<3; $i++) {
if ($i==1)
$obj->a = 100;
else
$obj->b = 200;
var_dump($obj);
}
[dongsong@localhost php-study]$ php stdobj_test.php
object(stdClass)#1 (1) {
["a"]=>
int(100)
}
object(stdClass)#1 (2) {
["a"]=>
int(100)
["b"]=>
int(200)
}