php隨手記

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.php

5.==和===的區別:==會在把兩個值自動轉換成同類型後再比較,而===在比較前不轉換

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)
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章