http://www.laruence.com/2015/05/28/3038.htmlphp
CentOS服務器上, 當你設置了小於1000ms的超時之後, curl不會發起任何請求, 而直接返回超時錯誤(Timeout reached 28).html
原來, 這裏面有一個坑, CURL默認的, 在Linux系統上, 若是使用了系統標準的DNS解析, 則會使用SIGALARM來提供控制域名解析超時的功能, 可是SIGALARM不支持小於1s的超時, 因而在libcurl 7.28.1的代碼中(注意中文註釋行):mysql
int Curl_resolv_timeout(struct connectdata *conn, const char *hostname, int port, struct Curl_dns_entry **entry, long timeoutms) { ....... ....... #ifdef USE_ALARM_TIMEOUT if(data->set.no_signal) /* Ignore the timeout when signals are disabled */ timeout = 0; else timeout = timeoutms; if(!timeout) /* USE_ALARM_TIMEOUT defined, but no timeout actually requested */ return Curl_resolv(conn, hostname, port, entry); if(timeout < 1000) //若是小於1000, 直接超時返回 /* The alarm() function only provides integer second resolution, so if we want to wait less than one second we must bail out already now. */ return CURLRESOLV_TIMEDOUT; .... ....
<?php curl_setopt($ch, CURLOPT_NOSIGNAL, 1); ?>
這樣就能夠支持了。sql
在比較新的PHP版本中,CURLOPT_NOSIGNAL是默認啓用的,因此能夠不用設置了。數組
能夠純粹瞭解一下就行吧。安全
關於PHP的浮點數, 我以前寫過一篇文章: 關於PHP浮點數你應該知道的(All ‘bogus’ about the float in PHP)服務器
不過, 我當時遺漏了一點, 也就是對於以下的這個常見問題的回答:less
<?php $f = 0.58; var_dump(intval($f * 100)); //爲啥輸出57 ?>
爲啥輸出是57啊? PHP的bug麼?dom
我相信有不少的同窗有過這樣的疑問, 由於光問我相似問題的人就不少, 更不用說bugs.php.net上常常有人問…curl
要搞明白這個緣由, 首先咱們要知道浮點數的表示,
計算機專業科班出身的我,表示理解這個並不難。
<?php $dbh = new PDO('mysql:host=localhost;dbname=test', "test"); $query = <<<QUERY INSERT INTO `user` (`username`, `password`) VALUES (:username, :password); QUERY; $statement = $dbh->prepare($query); $bind_params = array(':username' => "laruence", ':password' => "weibo"); foreach( $bind_params as $key => $value ){ $statement->bindParam($key, $value); } $statement->execute();
最後執行的確實下面的sql。
INSERT INTO `user` (`username`, `password`) VALUES ("weibo", "weibo");
究其緣由, 也就是bindParam和bindValue的不一樣之處, bindParam要求第二個參數是一個引用變量(reference).
解決方法:
A. 不要使用foreach, 而是手動賦值
$statement->bindParam(":username", $bind_params[":username"]); //$value是引用變量了 $statement->bindParam(":password", $bind_params[":password"]);
B. 使用bindValue代替bindParam, 或者直接在execute中傳遞整個參數數組.
<?php $dmcryptText = "This string was AES-256 / CBC / ZeroBytePadding encrypted."; $key = pack('H*', "bcb04b7e103a0cd8b54763051cef08bc55abe029fdebae5e1d417e2ffb2a00a3"); # 顯示 AES-128, 192, 256 對應的密鑰長度: # #16,24,32 字節。 $key_size = strlen($key); echo "Key size: " . $key_size . ", key: $key\n"; //$size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB); //$iv = mcrypt_create_iv($size); //注意這裏 $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); $iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM); echo "Iv size: " . $iv_size . ", iv: $iv\n"; # 建立和 AES 兼容的密文(Rijndael 分組大小 = 128) # 僅適用於編碼後的輸入不是以 00h 結尾的 # (由於默認是使用 0 來補齊數據) $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $dmcryptText, MCRYPT_MODE_CBC, $iv); echo base64_encode($ciphertext) . "\n";
這裏的問題就在於/dev/random, 它的random pool依賴於系統的中斷來產生. 當系統的中斷數不足, 不夠產生足夠的隨機數, 那麼嘗試讀取的進程就會等待, 也就是會hang住, 來看一個簡單的例子:
解決的辦法就是, 改用/dev/urandom, /dev/urandom也是一個產生隨機數的設備, 可是它不依賴於系統中斷.
Weibo上SAE的同窗 @胥昕ops提供了一個不須要修改PHP代碼的解決方案:
胥昕ops: SAE 二三月份遇到的這個問題,一條命令秒殺此問題,
$ rngd -r /dev/urandom -o /dev/random -t 1
用urandom的結果填充entropy池子,這樣既保證了entropy池的數量,也保證了隨機性
然而, 爲何PHP使用/dev/random做爲默認, 這是由於理論上來講, /dev/urandom在必定的狀況下, 可能會被可預測(參看: /dev/random), 因此通常上認爲, /dev/urandom不如/dev/random安全.
後記, 你們看手冊, 必定也要看手冊下面的評論, 呵呵, 有不少東西在評論中, 是有提到的, 以下面這條評論, 來自mcrypt_create_iv:
關於使用include仍是include_once(如下,都包含require_once), 這個討論很長了, 結論也一直有, 就是儘可能使用include, 而不是include_once, 之前最多的理由的是, include_once須要查詢一遍已加載的文件列表, 確認是否存在, 而後再加載.
解釋的比較複雜,懶得解釋了,反正儘可能少用。
排除這些技術因素, 我也一直認爲, 咱們應該使用include, 而不是include_once, 由於咱們徹底能作到本身規劃, 一個文件只被加載一次. 還能夠藉助自動加載, 來作到這一點.
你使用include_once, 只能證實, 你對本身的代碼沒信心.
這篇講得不是很詳細,我也沒有可以重現出來,估計是個人打開方式不對,評論裏面不少也是說不知道怎麼apc_bin_load的,Google了半天仍是沒有可以解決,因此我就說服本身別去想了,估計也用不上。若是真的要用的話,那麼試試Facebook的HHVM或者PHP7,估計效果也比這個強。