<![CDATA[張宴的博客]]> http://www.lukangtou.cn/index.php zh-cn http://www.lukangtou.cn/pthreads/ <![CDATA[PHP 真正多線程的使用]]> 張宴 <net@s135.com> Tue, 17 Dec 2013 03:17:53 +0000 http://www.lukangtou.cn/pthreads/
  我之前的文章中說過,大多數網站的性能瓶頸不在PHP服務器上,因為它可以簡單地通過橫向增加服務器或CPU核數來輕松應對(對于各種云主機,增加VPS或CPU核數就更方便了,直接以備份鏡像增加VPS,連操作系統、環境都不用安裝配置),而是在于MySQL數據庫。如果用 MySQL 數據庫,一條聯合查詢的SQL,也許就可以處理完業務邏輯,但是,遇到大量并發請求,就歇菜了。如果用 NoSQL 數據庫,也許需要十次查詢,才能處理完同樣地業務邏輯,但每次查詢都比 MySQL 要快,十次循環NoSQL查詢也許比一次MySQL聯合查詢更快,應對幾萬次/秒的查詢完全沒問題。如果加上PHP多線程,通過十個線程同時查詢NoSQL,返回結果匯總輸出,速度就要更快了。我們實際的APP產品中,調用一個通過用戶喜好實時推薦商品的PHP接口,PHP需要對BigSea NoSQL數據庫發起500~1000次查詢,來實時算出用戶的個性喜好商品數據,PHP多線程的作用非常明顯。

  PHP擴展下載:https://github.com/krakjoe/pthreads
  PHP手冊文檔:http://php.net/manual/zh/book.pthreads.php

  1、擴展的編譯安裝(Linux),編輯參數 --enable-maintainer-zts 是必選項:
cd /Data/tgz/php-5.5.1
./configure --prefix=/Data/apps/php --with-config-file-path=/Data/apps/php/etc --with-mysql=/Data/apps/mysql --with-mysqli=/Data/apps/mysql/bin/mysql_config --with-iconv-dir --with-freetype-dir=/Data/apps/libs --with-jpeg-dir=/Data/apps/libs --with-png-dir=/Data/apps/libs --with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --enable-mbregex --enable-fpm --enable-mbstring --with-mcrypt=/Data/apps/libs --with-gd --enable-gd-native-ttf --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --enable-opcache --with-pdo-mysql --enable-maintainer-zts
make clean
make
make install        

unzip pthreads-master.zip
cd pthreads-master
/Data/apps/php/bin/phpize
./configure --with-php-config=/Data/apps/php/bin/php-config
make
make install


vi /Data/apps/php/etc/php.ini

添加:
extension = "pthreads.so"


  2、給出一段PHP多線程、與For循環,抓取百度搜索頁面的PHP代碼示例:

Tags - , , , ]]>
http://www.lukangtou.cn/taobaoke_click_urls/ <![CDATA[根據淘寶商品 num_iid 批量生成淘寶客鏈接的 PHP 函數]]> 張宴 <net@s135.com> Thu, 16 Feb 2012 06:08:13 +0000 http://www.lukangtou.cn/taobaoke_click_urls/ http://blog.www.lukangtou.cn/taobaoke_click_urls/]

  根據淘寶商品 num_iid 批量生成淘寶客(什么是淘寶客?)鏈接的 PHP 文件內容如下。

  淘寶 API 有調用次數限制,一次 API 調用,可以最大返回40個商品的淘寶客鏈接,因此,在本函數內,如果需要批量生成的淘寶商品 num_iid 數大于40,將按照40個一次,分多次調用。如果調用淘寶 API 查詢過的商品 num_iid,不管其是否有淘寶客鏈接(有些商品沒有淘寶客推廣鏈接),都將利用 Memcached 緩存起來,下次直接查緩存,不會重復調用淘寶 API。

<?php
require_once(dirname(__FILE__).'/TopSdk.php'); //引用淘寶開放平臺 API SDK

function object2Array($d)
{
        if (is_object($d))
        {
            $d = get_object_vars($d);
        }

        if (is_array($d))
        {
            return array_map(__FUNCTION__, $d);
        }
        else
        {
            return $d;
        }
}


/*********************************************
* 函數名:get_taobaoke_link ($num_iids)
* 函數用途:通過淘寶商品 num_iids 獲取其對應的淘寶客手機版鏈接
* 創建時間:2012-02-14
* 創建人:張宴 net@www.lukangtou.cn
* 參數說明:
*    $num_iids   淘寶商品ID(支持多個商品)數組,示例如下:
*          $num_iids[] = "13583512568";
*          $num_iids[] = "10809380078";
*          $num_iids[] = "10809380079";  
* 返回值:
*    下標為淘寶商品 num_iid ,值為淘寶客鏈接 click_url 的二維數組。如果無淘寶客鏈接,click_url 為空字符串,示例如下:
*          array(3) {
*            ["13583512568"]=>
*            string(191) "http://auction1.wap.taobao.com/auction/item_detail-0db2-13583512568.jhtml?tks=jUTwPLMDtUUNEZhqfEuTZqkZhGw1LA7%2BzCJBXCj27NpurHxjZN70Amg0DVaFU61pfnHwW%2FI4MZGm%0Awgb69kbb1NL8uwtu%2BDnyAunBCVDP"
*            ["10809380078"]=>
*            string(187) "http://auction1.wap.taobao.com/auction/item_detail-0db2-10809380078.jhtml?tks=jUTwPLMDtUUNEGWhOOgVVuX%2BJKYt7fesyuZjEe7hvmpTJxYDfK8i1Wpvfl7lwI7nzD9W8M352v6E%0AyuUtsKun81AGltKzJWCYPiVDiOeC"
*            ["10809380079"]=>
*            string(0) ""
*          }  
*********************************************/
function get_taobaoke_link ($num_iids) {
  $memcache = new Memcache;
  $memcache->connect('127.0.0.1', 11911); //Memcached 緩存服務器地址
  $click_urls = $memcache->get($num_iids);
  
  foreach ($num_iids AS $num_iid) {
    if (!isset($click_urls[$num_iid])) {
      $tbapi_num_iids_arr[] = $num_iid;
    }
  }
  
  if (!empty($tbapi_num_iids_arr)) {
    $numbers = count($tbapi_num_iids_arr);
    $numbers_max = 40; //淘寶 API 限制最大返回40條記錄
    if ($numbers > 0) {
      $numbers_times = ceil($numbers / $numbers_max); //第一層循環的循環次數
      $numbers_start = 0;
      $numbers_end = $numbers_max;
      for ($numbers_i = 1; $numbers_i <= $numbers_times; $numbers_i++) {
        for ($numbers_j = $numbers_start; $numbers_j < $numbers_end; $numbers_j++) {
          if ($numbers_j >= $numbers) {
            break;
          }
          $tbapi_num_iids_arr_sp[] = $tbapi_num_iids_arr[$numbers_j];
        }
        
        $numbers_start = $numbers_start + $numbers_max;
        $numbers_end = $numbers_end + $numbers_max;
        
        $tbapi_num_iids = implode(",", $tbapi_num_iids_arr_sp);
        $c = new TopClient;
        $c->appkey = 12498835; //淘寶開放平臺 API 接口 App Key
        $c->secretKey = "745db5f8e316f9f1aa8310a7568d6566"; //淘寶開放平臺 API 接口 App Secret
        $c->format = "json";
        $req = new TaobaokeItemsConvertRequest;
        $req->setFields("num_iid,click_url");
        $req->setNumIids($tbapi_num_iids);
        $req->setPid(29509662); //淘寶聯盟(阿里媽媽)PID
        $req->setIsMobile("true"); //如果要生成手機頁面的淘寶客鏈接,選擇 true;網頁版選擇 false
        $resp = $c->execute($req);
        $res = object2Array($resp);
  
        if (isset($res["taobaoke_items"]["taobaoke_item"])) {
          $links = $res["taobaoke_items"]["taobaoke_item"];
          foreach ($links as $value) {
            $memcache->set($value["num_iid"], $value["click_url"], MEMCACHE_COMPRESSED, 0);
            $click_urls[(string)$value["num_iid"]] = $value["click_url"];
          }
        }
        
        unset($tbapi_num_iids_arr_sp);
        unset($tbapi_num_iids);
        unset($resp);
        unset($res);
        unset($links);
        unset($value);
      }
    }
  }
  
  foreach ($num_iids AS $num_iid) {
    if (!isset($click_urls[$num_iid])) {
      $memcache->set($num_iid, "", MEMCACHE_COMPRESSED, 0);
      $click_urls[(string)$num_iid] = "";
    }
  }  
  
  $memcache->close();
  return $click_urls;
}

//演示
$num_iids[] = "13583512568";
$num_iids[] = "10809380078";
$num_iids[] = "10809380079";
$click_urls = get_taobaoke_link ($num_iids);
var_dump($click_urls);
?>




  淘寶開放平臺(http://open.taobao.com/) PHP SDK 下載:
............

Tags - , , ]]>
http://www.lukangtou.cn/2011phptc/ <![CDATA[2011中國PHP技術高峰論壇:PHP在金山游戲運營中的應用]]> 張宴 <net@s135.com> Sun, 08 May 2011 11:40:41 +0000 http://www.lukangtou.cn/2011phptc/ 2011中國PHP技術高峰論壇”上的演講PPT:

  下載地址1(國外服務器):http://blog.www.lukangtou.cn/attachment/201105/2011phptc_zy.zip

  下載地址2(國內服務器):http://ishare.iask.sina.com.cn/f/15231659.html



  點擊在新窗口中瀏覽此圖片

  以下是我在會議主辦方對演講文字速錄的基礎上,修正錯漏內容,整理之后,對應到每頁PPT的文字內容:

  [PPT No.1]
  大家下午好,現在我來跟大家分享的是PHP在金山游戲運營中的應用,包括團隊協助開發實現方式、網站Web架構設計、游戲運營平臺設計這些信息。

  [PPT No.2]
  我議題主要有兩個,一個是金山游戲官方網站的一些應用,另一個是金山游戲運營系統Keyes中的架構設計。

  [PPT No.3]
  金山游戲官方網站包括用戶中心、客服系統、論壇、視頻、各游戲官網,以及其他跟游戲相關的一些產品,主要采用64位CentOS Linux系統、Nginx、PHP 5.2版本、MySQL 5.5。

  [PPT No.4]
  首先來看團隊協作開發。我們肯定遇到過這樣一種情況,在很多項目中,都是多個人同時開發,涉及到開發環境和測試環境不一樣。我們很多PHP工程師,都是在Windows上開發代碼,雖然Windows上也可以配置Nginx+PHP+MySQL環境,但是,由于測試環境、生產環境都是Linux系統,而且一些功能只能在Linux下運行,還有一些PHP擴展(例如:分布式圖片處理、金山通行證加密擴展),也只能運行在Linux環境中。當我們在Windows上修改完幾行PHP代碼,想馬上看一下執行結果,如果利用FTP之類的工具傳到Linux測試服務器上再測試,就太慢了。如果同一臺Linux測試服務器上,有多少人同時開發,你上傳上去PHP文件,可能會覆蓋別人上傳的同名文件,就沒有辦法做到版本控制。

  [PPT No.5]
  我們從圖中可以看到,假如是程序員A和B都在Windows上開發代碼,由于Nginx與PHP之間采用的是TCP FastCGI協議通訊,因此,兩者可以分離到不同的服務器上。我們可以把Nginx安裝在程序員各自的Windows PC機上,用本機的Nginx處理HTTP請求,用Linux測試服務器上的php-cgi程序,處理PHP請求。程序員在Windows上開發程序,保存之后,不用做任何上傳操作,即可用Linux上的php-cgi調試程序。從圖中這個流程可以看到,首先,兩個程序員分別從SVN版本庫,獲取到一個項目的最新版本,各自進行一些修改。兩人修改程序時,采用的是同一臺Linux測試服務器的php-cgi,對各自PC機上的PHP程序進行調試。在PC機上本地測試沒有問題,可以提交到SVN版本庫。我們做了一個自動同步程序,利用SVN鉤子,在每次發生svn commit提交時,在對應的測試服務器的對應項目路徑內,執行svn update,將最新修改到文件同步到測試服務器。后來發現有一些問題,如果我們一個項目的目錄、程序文件特別多的話,svn update需要遍歷掃描目錄列表,非常慢。因為我們的SVN是和Apache結合起來使用的,Apache可以記錄日志,于是,我們進行了改進,將SVN提交日志記錄到Linux下的命名管道內,再用一個程序從命名管道內讀取日志,只svn update每次修改的幾個文件,這樣,速度就非??炝?。設置hosts為Linux測試服務器的IP,就可以測試多位程序員代碼合并后的效果了。

............

Tags - ]]>
http://www.lukangtou.cn/post/459/ <![CDATA[Windows 和 Linux 下生成以當前時間命名的文件]]> 張宴 <net@s135.com> Mon, 28 Feb 2011 07:33:09 +0000 http://www.lukangtou.cn/post/459/
  Windows BAT批處理文件:
@echo off
set time_hh=%time:~0,2%
if /i %time_hh% LSS 10 (set time_hh=0%time:~1,1%)
set filename=%date:~,4%%date:~5,2%%date:~8,2%_%time_hh%%time:~3,2%%time:~6,2%
echo test >> %filename%.txt


  Linux Shell 腳本:
#!/bin/sh
echo test >> $(date -d "today" +"%Y%m%d_%H%M%S").txt

]]>
http://www.lukangtou.cn/php_sqlserver_freetds/ <![CDATA[Linux 下 PHP 5.2.x 連接 SQL Server 數據庫 FreeTDS 配置筆記]]> 張宴 <net@s135.com> Fri, 25 Jun 2010 10:00:35 +0000 http://www.lukangtou.cn/php_sqlserver_freetds/
  1、編譯安裝FreeTDS
mkdir -p /data0/software/
cd /data0/software/
wget ftp://ftp.ibiblio.org/pub/Linux/ALPHA/freetds/stable/freetds-stable.tgz
tar zxvf freetds-stable.tgz
cd freetds-0.82/
./configure --prefix=/usr/local/webserver/freetds --with-tdsver=8.0 --enable-msdblib
make && make install
cd ../

echo "/usr/local/webserver/freetds/lib/" > /etc/ld.so.conf.d/freetds.conf
ln -s /usr/local/webserver/freetds/lib/libsybdb.so.5.0.0 /usr/local/webserver/freetds/lib/libsybdb.so.4
/sbin/ldconfig

rm -f /usr/local/webserver/freetds/etc/freetds.conf
vi /usr/local/webserver/freetds/etc/freetds.conf

  輸入以下內容:
引用
[global]
        # TDS protocol version
;       tds version = 4.2

        # Whether to write a TDSDUMP file for diagnostic purposes
        # (setting this to /tmp is insecure on a multi-user system)
;       dump file = /tmp/freetds.log
;       debug flags = 0xffff

        # Command and connection timeouts
;       timeout = 10
;       connect timeout = 10

        # If you get out-of-memory errors, it may mean that your client
        # is trying to allocate a huge buffer for a TEXT field.
        # Try setting 'text size' to a more reasonable limit
        text size = 64512

        host = mssql.yourdomain.com
        port = 1433
        tds version = 8.0
        client charset = UTF-8


  2、編譯安裝PHP自帶MSSQL擴展
  進入本地已存在的php-5.2.XX源碼包目錄:
cd /data0/software/php-5.2.XX/ext/mssql/
/usr/local/webserver/php/bin/phpize
./configure --with-php-config=/usr/local/webserver/php/bin/php-config --with-mssql=/usr/local/webserver/freetds/
make && make install


  3、在php.ini配置文件中增加mssql.so
vi /usr/local/webserver/php/etc/php.ini

  增加一行:
引用
extension = "mssql.so"


  4、重啟PHP FastCGI
/usr/local/webserver/php/sbin/php-fpm restart


  5、測試文件(test_mssql.php):

Tags - , , , , , ]]>
http://www.lukangtou.cn/google_ssl/ <![CDATA[快速跳轉到Google SSL 中文版的網址:ggssl.com [此文被墻,無法瀏覽]]]> 張宴 <net@s135.com> Fri, 28 May 2010 15:18:25 +0000 http://www.lukangtou.cn/google_ssl/ https://www.google.com),可以保護用戶的搜索關鍵字和搜索結果不被ISP等第三方機構攔截、竊取,不被墻連接重置。

  國內用戶訪問 https://www.google.com 默認情況下會跳轉到谷歌香港 http://www.google.com.hk,解決方法為先點擊“Google.com in English“訪問 http://www.google.com/ncr (僅需要點擊一次),該網址會種一個Cookie,防止跳轉,再設置搜索語言為中文,再輸入 https://www.google.com 即可,比較麻煩。

  本人將這一復雜的流程簡化為一個域名:ggssl.com,只需要訪問:http://ggssl.com,即可利用腳本快速跳轉到 Google SSL 加密搜索中文版。第一次訪問自動設置并跳轉,以后訪問立即自動跳轉。

  Google SSL 搜索快速跳轉域名:http://ggssl.com ]]>
http://www.lukangtou.cn/ajaxcdr/ <![CDATA[AJAXCDR:利用 Flash 完美解決 JavaScript 和 AJAX 跨域 HTTP POST/GET 表單請求[原創]]]> 張宴 <net@s135.com> Mon, 09 Mar 2009 03:54:45 +0000 http://www.lukangtou.cn/ajaxcdr/ http://blog.www.lukangtou.cn/ajaxcdr/]

  最近的一個項目中,需要通過 JavaScript 提交表單數據到另一個域名下的PHP接口(因為數據較大,需要HTTP POST方式提交),并獲取PHP接口的返回值,在頁面無刷新、無跳轉的情況下,更新div標簽內的內容。

  瀏覽器出于安全考慮,是不允許JavaScript代碼進行跨域操作。JavaScript 和 AJAX 跨域訪問分為兩大類,一是本域和子域的交互,二是本域和其他域的交互。

  一、本域和子域的交互:www.www.lukangtou.cn 和 blog.www.lukangtou.cn
  二、本域和其他域的交互:blog.www.lukangtou.cn 和 api.bz

  本域和子域的交互,可以通過iframe設置兩個域名document.domain = "www.lukangtou.cn",實現統一www.lukangtou.cn域下的跨域訪問。

  本域和其他域的交互,可以通過iframe、代理、JS創建動態腳本等幾種方法來實現,這里有篇文章對幾種方法作了簡要的介紹。

  iframe、JS創建動態腳本這兩種方法,需要開發者能控制兩個域,兩端都要編寫相應的代碼,非常麻煩。在本域服務器上用PHP寫個代理中轉程序,讓本域PHP程序去讀取遠程其他域的數據再返回給自己,是常用的方法。但是,在本域“前端是CDN或Squid緩存服務器,后端才是PHP應用程序服務器”的系統架構下,穿透CDN或Squid去訪問不能被緩存的PHP代理中轉程序,效率是很低的。



  國外有人嘗試用 Flash 做 JavaScript 和 AJAX 跨域訪問中轉,無疑是一個好方法。JavaScript 將數據提交給本域下的 Flash,通過 Flash 中轉去訪問其他域的接口,條件只需要其他域的根目錄下有一個crossdomain.xml文件,文件中設置允許所有域名或允許本域訪問即可。很多網站的API域名都提供了crossdomain.xml文件。

  例如:
  1、新浪博客的crossdomain.xml文件(http://blog.sina.com.cn/crossdomain.xml)設置了允許所有域名訪問;
  2、飯否API的crossdomain.xml文件(http://api.fanfou.com/crossdomain.xml)設置了允許所有域名訪問;
  3、校內網API的crossdomain.xml文件(http://api.xiaonei.com/crossdomain.xml)設置了允許所有域名訪問;
  4、優酷網的crossdomain.xml文件(http://www.youku.com/crossdomain.xml)設置了允許所有域名訪問;
  5、土豆網的crossdomain.xml文件(http://www.tudou.com/crossdomain.xml)設置了允許所有域名訪問;

  6、逍遙視頻的crossdomain.xml文件(http://v.xoyo.com/crossdomain.xml)設置了只允許*.xoyo.com域名訪問;
  7、網易的crossdomain.xml文件(http://www.163.com/crossdomain.xml)設置了只允許tech.163.com、sports.163.com等幾個域名訪問。



  本人在“Cross-domain AJAX using Flash”的基礎上,增加了對表單進行智能處理的功能,封裝了一個JavaScript包:AJAXCDR。通過 AJAXCDR,即可輕松地解決 JavaScript 和 AJAX 跨域 HTTP POST/GET 表單請求,支持IE、Firefox、谷歌Chrome等多種瀏覽器。

  AJAXCDR 擁有兩個文件:ajaxcdr.js 和 ajaxcdr.swf,AJAXCDR 擁有一個 JavaScript 函數 AjaxCrossDomainRequest() 和一個全局變量 AjaxCrossDomainResponse。

  一、AJAXCDR 下載:

............

Tags - , , , , , , , ]]>
http://www.lukangtou.cn/post/392/ <![CDATA[PHPSH:Facebook開發的PHP Shell的安裝與使用[原創]]]> 張宴 <net@s135.com> Tue, 13 Jan 2009 10:35:24 +0000 http://www.lukangtou.cn/post/392/ http://blog.www.lukangtou.cn/post/392/]

  PHPSH 是 Facebook 團隊開發的一款交互式 PHP Shell,可以方便地進行PHP命令行測試。

  網址:http://www.phpsh.org/

  安裝方法:
cd /opt/
wget http://www.phpsh.org/phpsh-latest.tgz
tar zxvf phpsh-latest.tgz
cd phpsh/
sed -i "s#php -q#/usr/local/webserver/php/bin/php -q#g" phpsh
chmod +x phpsh
ln -s /opt/phpsh/phpsh /bin/phpsh

  注意:上述安裝方法中的“/usr/local/webserver/php/bin/php”為您的PHP可執行文件路徑。


  使用示例:
[root@localhost ~]# phpsh
I can't find a tags file for you.  To enable tab completion in phpsh,
go to the root directory of your php code and run 'ctags -R',
(or whatever the analagous command is with your version of ctags,)
then run phpsh from that directory or a subdirectory of that directory.

Commandline: /usr/local/webserver/php/bin/php -q /opt/phpsh/phpsh.php
phpsh (c)2006 by Charlie Cheever and Dan Corson and Facebook, Inc.
type 'h' or 'help' to see instructions & features

New Feature: You can use the -c option to turn off coloring
php> = 3 + 4
7
php> = md5("ZhangYan")
28f91f3a4b62ce57b7a533e742e8aae1
php> echo date("Y-m-d H:i:s")
2009-01-13 15:28:19
php> $var = "blog.www.lukangtou.cn"
php> echo $var
blog.www.lukangtou.cn
php> $array = array(array(1,2,3), array("a" => "b", "c" => "d", "e" => "f"), 'g', 'h')
php> = $array
Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

    [1] => Array
        (
            [a] => b
            [c] => d
            [e] => f
        )

    [2] => g
    [3] => h
)

php> q

[root@localhost ~]# phpsh


Tags - , , , ]]>
http://www.lukangtou.cn/post/390/ <![CDATA[支持MSNP15協議與離線消息的PHP MSN Class,可實現MSN機器人]]> 張宴 <net@s135.com> Mon, 29 Dec 2008 16:05:33 +0000 http://www.lukangtou.cn/post/390/ http://blog.www.lukangtou.cn/post/390/]

  我之前的一篇文章《Linux服務器系統監控框架與MSN、E-mail、手機短信報警的實現》中提到MSN報警,當時使用的sendMsg類采用的是MSNP9協議,不支持離線消息。最近找到一個PHP MSN Class(http://code.google.com/p/phpmsnclass/),支持MSNP9 (MSN 6.2)和最新的MSNP15 (WLM 8.1)協議(MSNP15協議支持離線消息),可以作為MSN機器人使用,或者給MSN、雅虎通發消息。

  示例代碼:必須確保發送人、接收人的MSN互相加為好友。

............

Tags - , , , ]]>
http://www.lukangtou.cn/post/389/ <![CDATA[同一域名對應多個IP時,PHP獲取遠程網頁內容的函數[原創]]]> 張宴 <net@s135.com> Sun, 14 Dec 2008 16:01:32 +0000 http://www.lukangtou.cn/post/389/ http://blog.www.lukangtou.cn/post/389/]

  PHP獲取遠程網頁內容有多種方式,例如用自帶的file_get_contents、fopen等函數。
引用
<?php  
echo file_get_contents("http://blog.www.lukangtou.cn/abc.php");  
?>

  但是,在DNS輪詢等負載均衡中,同一域名,可能對應多臺服務器,多個IP。假設blog.www.lukangtou.cn被DNS解析到72.249.146.213、72.249.146.214、72.249.146.215三個IP,用戶每次訪問blog.www.lukangtou.cn,系統會根據負載均衡的相應算法訪問其中的一臺服務器。

  上周做一個視頻項目時,就碰到這樣一類需求:需要依次訪問每臺服務器上的一個PHP接口程序(假設為abc.php),查詢這臺服務器的傳輸狀態。

  這時就不能直接用file_get_contents訪問http://blog.www.lukangtou.cn/abc.php了,因為它可能一直重復訪問某一臺服務器。

  而采用依次訪問http://72.249.146.213/abc.php、http://72.249.146.214/abc.php、http://72.249.146.215/abc.php的方法,在這三臺服務器上的Web Server配有多個虛擬主機時,也是不行的。

  通過設置本地hosts也不行,因為hosts不能設置多個IP對應同一個域名。

  那就只有通過PHP和HTTP協議來實現:訪問abc.php時,在header頭中加上blog.www.lukangtou.cn域名。于是,我寫了下面這個PHP函數:
............

Tags - ]]>
http://www.lukangtou.cn/post/312/ <![CDATA[一個發送HTML郵件的PHP函數[原創]]]> 張宴 <net@s135.com> Wed, 21 Nov 2007 01:14:57 +0000 http://www.lukangtou.cn/post/312/
  函數說明:send_mail("發件人地址", "收件人地址", "郵件主題", "郵件正文");

  示例:send_mail($from, "info@www.lukangtou.cn", "這是郵件的主題", "<html><head></head><body><p><font color=red>這是郵件正文</font></p></body></html>");

  代碼如下:
............

Tags - ]]>
http://www.lukangtou.cn/post/311/ <![CDATA[PHP多進程并發控制的測試用例[原創]]]> 張宴 <net@s135.com> Fri, 16 Nov 2007 06:32:30 +0000 http://www.lukangtou.cn/post/311/ http://blog.www.lukangtou.cn]

  最近遇到一個問題,Linux下的PHP命令行程序作為守護進程,需要從隊列文件中讀一行數據,通過TCP協議發送給外地的接收服務器,再讀下一行數據,再發送。當本地與外地的網絡狀況不好時,有時候發送一條數據所耗費的時間就較長,累積起來容易造成隊列堵塞和延遲。

  于是,我準備用該PHP命令行程序生成多個子進程,將串行處理變成并行處理。最簡單的方法就是在PHP中用exec()或popen()函數將一個shell命令行推到后臺去執行,例如:
<?php
exec("/bin/sh /opt/zhangyan.sh &");
?>
  最后的&表示將shell腳本推到后臺去執行。

  但是這樣會有一個問題,如果推到后臺的進程太多,可能會導致服務器系統資源耗盡而崩潰,所以必須控制進程數量。



  我寫了一個PHP程序(/opt/zhangyan.php)、一個shell程序(/opt/zhangyan.sh)作為測試用例。

  程序的邏輯:
  1、設置/opt/zhangyan.php最多允許生成500個子進程;
  2、當/opt/zhangyan.php讀取到一條數據后,將允許生成的子進程數減1(空閑進程數$p_number=500-1=499),然后將數據交給/opt/zhangyan.sh去后臺處理,不等待/opt/zhangyan.sh處理結束,繼續讀取下一條數據;
  3、當允許生成的子進程數減至0時(空閑進程數$p_number=0),/opt/zhangyan.php會等待1秒鐘,然后檢查后臺還有多少個/opt/zhangyan.sh子進程尚未處理結束;
  4、如果1秒鐘之后/opt/zhangyan.php發現后臺的/opt/zhangyan.sh子進程數還是500(空閑進程數$p_number=0),會繼續等待1秒鐘,如此反復;
  5、如果/opt/zhangyan.php發現后臺尚未處理結束的/opt/zhangyan.sh子進程數減少到300個了(空閑進程數$p_number=500-300=200),那么/opt/zhangyan.php會再往后臺推送200個/opt/zhangyan.sh子進程;

............

Tags - , ]]>
http://www.lukangtou.cn/post/285/ <![CDATA[采用curl庫在PHP程序之間傳遞數組[原創]]]> 張宴 <net@s135.com> Thu, 16 Aug 2007 10:59:44 +0000 http://www.lukangtou.cn/post/285/ http://blog.www.lukangtou.cn]

  最近在工作中遇到一個問題:a.php程序需要將接收到的數據同時寫到“線上運行的正式數據庫”和“進行開發調試的測試數據庫”。而測試數據庫可能經常會面臨對表結構、字段、配置信息做調整等問題,很不穩定,發生錯誤的概率很高,如果用a.php程序同時寫“正式數據庫”和“測試數據庫”,勢必影響到線上運行的正式服務。

  于是,我想到用PHP curl擴展庫將生成的$data數組post傳遞一份給b.php程序,然后a.php程序繼續往下執行寫“正式數據庫”的代碼。a.php程序將$data數組傳遞給b.php程序就完事了,至于b.php如何處理,就不關a.php的事了,b.php程序即使寫“測試數據庫”失敗,也不會對a.php程序造成影響。

  點擊在新窗口中瀏覽此圖片

  按照這種思路,我寫了a.php和b.php的代碼:

  a.php程序源代碼:
............

Tags - ]]>
http://www.lukangtou.cn/post/284/ <![CDATA[PHP截取中文字符串不出現?號的解決方法[原創]]]> 張宴 <net@s135.com> Wed, 15 Aug 2007 10:51:21 +0000 http://www.lukangtou.cn/post/284/ http://blog.www.lukangtou.cn]

  當PHP截取中英文混合字符串時,最后一個漢字經常被拆成兩半,例:截取字符串的前18個字
............

Tags - ]]>
http://www.lukangtou.cn/post/257/ <![CDATA[利用Xdebug分析PHP程序,找出性能瓶頸[原創]]]> 張宴 <net@s135.com> Thu, 28 Jun 2007 02:17:46 +0000 http://www.lukangtou.cn/post/257/ http://blog.www.lukangtou.cn]

  經濟學中有一條著名的80-20定律,引用到編程中,就是:80%的性能瓶頸是由20%的代碼引起的。借助PHP的XDebug擴展,可以有效地找出這20%的代碼。

  一、安裝配置
  1、下載PHP的XDebug擴展,網址:http://xdebug.org/

  2、在Linux下編譯安裝XDebug
引用
tar -xzf xdebug-2.0.0RC3.gz
cd xdebug-2.0.0RC3
/usr/local/php/bin/phpize
./configure --enable-xdebug
cp modules/xdebug.so /usr/local/php/lib/php/extensions/no-debug-non-zts-20020429/

  注:/usr/local/php/lib/php/extensions/no-debug-non-zts-20020429/不同的PHP版本路徑不同,也不一定要放在該路徑,可以在zend_extension_ts中自行指定xdebug.so所在位置。

............

Tags - , ]]>
在线精品国产在线视频