寫!

PHP7 Upgrade

把mysql_ 的function 棄用而完全轉為wrapper 已經是很多很多年前的事了。

直到PHP7的升級才迫得我去一直過做一次。

事實上在一年前的某個星期已經完成了40%的工作, 但這次的升級有很多意想不到的事。

PHP7 除了在opcache 情況下執行速度以倍數快了之外和有幾個function 移除之外。最致命的是compile extension 時很多底層的C 記憶體常數都換了。

這導致ZKIZ 一直依賴的分詞(基於C)和PHPRedis(基於C)都無法使用了。

不兼度的擴展和十分分散的古老代碼令升級的工作量大增, 前後足足花了近三天的時間去修正代碼。

PHPRedis 的官方Github 甚至還沒有對於PHP7的make 作出升級兼容。這對我使用的網絡API 和數據庫的緩衝都有了致命的影響,在顧及負載和長期使用的情況下,我選擇了即時制作Redis 的存取Class。

在眾多的阻礙下,我一度萌生退回PHP5.6的想法,但幸好我當時是覺得退回也不是不費精力的,而一度進入Flow 狀的本人竟又在Production 馬上動起來,首先當然是馬上在Redis的官網查看,把現存官方有記錄的class 看一次,而對使用Redis經驗告訴我,Predis作為緩衝類會有性能問題,而C系的在PHP7下卻會有建置問題,依存Framework 的會讓我拆解邏輯十分費時和精力,沒有Recommend符號的Class 幾乎都有明顯bug...bug..bug 沒有所謂啊! 反正我會fix, 我甚至不要unit test, 我只要馬上能理解的就可以了。我看到: PHP Redis implementation / wrapper ,名字雖長,但那老實在低調的氣質在那wrapper 中完完全全地發放著。

它只有一個指令, 就叫cmd... 甚麼hashstore, set, get, array, serialize 等等都沒有包裝。如我所願, 它就是把socket 層包裝好給我傳command 而已。我改寫了set 和get, 加入了expire, exists, del 等, 不下5 分鐘就成功了。

算是回避了PHPRedis 不能建置的問題。也相信這個socket 傳送在PHP7下會保證到運作性能。而在一日後的測試中, 發現它在opcache 下的表現和PHPRedis 的PHP擴展幾乎一樣。

然後到分詞, 我用的是一個名氣甚低的國產分詞器, 對於分詞器, 用PHP 來實作我還是對性能上缺乏信心, 但在15分鐘的尋找下, 發現他在幾天上的Github master 上已經作出workaround 了。中間經過不少迷茫的時期, 有試過把舊的.so 加載, 也有試過自行跟據錯誤試著修正建置流程, 但靠master tree 還是有驚無險地把make 跑完。

然後系統勉強重新上線了, 接種而來的是早預期到的新Runtime error/warning/notice, 整合7年以來的deprecated function 實在不是一時三刻的事。crontab 中包含的永遠才是重中之重。因為連我也不能馬上推算運行失敗後有沒有人會察覺, 然後造成不必要的除錯困擾。

然後因為錯誤實在太多, 優先解決的當然就是出現最多而最可見的。然後就是一連幾個小時對著神聖的 tail -f *.error.log 來修。這從每秒鐘都要用ctrl-c 停止來debug 到幾乎看不到404以外的問題。中間的過程實在十分漫長卻十分有快感, 我十分感謝大量的流量為我這debug 的過程帶來的重大幫助, 我想這是在任何一間企業都無法建立的升級環境。

在這一天做了幾乎一年份的issue和patch,畢生難忘。

發表時間:2016年2月12日 | 評論 (0) | 全文

F# 學習筆記 7 介面

// 型別: 介面
// ---------------------------------------------------------------
 
type IPeekPoke = 
    abstract Peek: unit -> int
    abstract Poke: int -> unit
 
// 型別: 含介面實作的類別
// ---------------------------------------------------------------
 
/// 計算自身被查詢次數的 Widget
type Widget(initialState:int) = 
    /// Widget 的內部狀態
    let mutable state = initialState
 
    // 實作 IPeekPoke 介面
    interface IPeekPoke with 
        member x.Poke(n) = state <- state + n
        member x.Peek() = state 
        
    /// Widget 被查詢過嗎?
    member x.HasBeenPoked = (state <> 0)
 
 
let widget = Widget(12) :> IPeekPoke
 
widget.Poke(4)
let peekResult = widget.Peek()
 
// 列印
// ---------------------------------------------------------------
 
// 列印整數
printfn "peekResult = %d" peekResult 
 
// 使用 %A 列印結果以進行一般列印
printfn "listC = %A" listC


這是最後一份筆記了&nbsp;
新關鍵字是abstract,mutable 還有&lt;-&nbsp;
十分難以理解的東西, 先從介面定義開始說起&nbsp;
abstract Peek: 是輸入unit 而輸出int,&nbsp;
unit 是一個特別的值, 這在functional 語言中十分常見, 要說定義的話, 就是它只有一個叫() 或者叫null 的值那就是說是不用輸入 Poke 則是相反, 輸入int 而不作出回應 &nbsp;




實作時: 把initialState 放進去, mutable 是F#的關鍵字, 用途是令state 可以裡重新assign (發現以前的都不可以了吧@@ 就是如果mutable 不放進去的話, 是沒法像其他語言那樣a=1 然後a=2 的, 說起來functional 語言很像算式, 但這樣想的話它就不能用來推動任何東西了, 我也就在吐嘈)&nbsp;




interface IPeekPoke with &nbsp;member ....member 只可以是在abstract 中提過的成員&nbsp;




Poke 會輸入n 然後state 變為state+n Peek 是回傳state &nbsp;
:&gt; 用法是 class(params) :&gt; interface, interface 是強制的, 像是宣告型態一樣, 就當給自己提示吧
發表時間:2013年3月6日 | 評論 (0) | 全文

In PHP a string is actually an array

In PHP a string is actually an array, so $foo ="hotscripts", you could access the "h" with $foo[0], the "o" with $foo[1], and so on.

-------------------

delete from zm_tags WHERE length(tag) < 4 AND tag + 0 <> 0

發表時間:2010年12月10日 | 評論 (0) | 全文

.htaccess - Allow Only By Referer

Good afternoon-

I have browsed the forums as well as the web looking for an answer to this question. Hope someone out there can help.

I need to create a .htaccess file that will only allow the files in the folder to be seen if the "referer" is from a particular site (or possibly two sites). I have found a lot of solutions out there for people who want to block specific sites, but I can't seem to figure out how to only allow specific sites. I have done some trial and error based on some of the things I have found, but with no luck.

Any ideas?

Thanks in advance!

David

------------------------------------

ANS:

Hi David,

Welcome to the forums

I haven't tested it, but try;

RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_REFERER} !^http://www\.your_domain_name\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^http://www\.OKdomain1\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^http://www\.OKdomain2\.com/ [NC]
RewriteRule ^.*$ http://www.your_domain_name.com/not_allowed_here.htm [R=301,L]

or I'd try something along those lines anyway - with the not_allowed_here.htm being a page I redirected all those I don't want to.

發表時間:2010年9月13日 | 評論 (0) | 全文

APC(Alternative PHP Cache)


 APC是一種php的緩存解決方案,目前以pecl方式發佈,有消息說將會出現在php6版本的內核.

 
一.安裝方法

1)從http://pecl.php.net/package/apc下載相應版本
2)解壓
3)進入源碼目錄
4)執行php安裝目錄下的bin/phpize
5)./configure --enable-apc --enable-apc-mmap --with-apxs=path-to-apache/bin/apxs --with-php-config=path-to-php/bin/php-config
6)make && make install
7)將生成的apc.so加載到php.ini(extesion=apc.so,注意extension_dir的設置)
一般地,編譯生成的.so會在php安裝路徑的lib/php/extensions下
8)重啟,apache
 
寫一個phpinfo看看
 



 
註:windows下,只要到http://snaps.php.net/的相應分支下下載php_apc.dll,再在php.ini中加載即可
 
二.用法
 
apc的用法比較簡單,只有幾個函數,列舉如下
apc_clear_cache() 清除apc緩存內容
默認(無參數)時,只清除系統緩存,要清除用戶緩存,需用'user'參數
apc_define_constants ( string key, array constants [, bool case_sensitive] ) 
將數組constants以常量加入緩存
apc_load_constants (string Key)
取出常量緩存
apc_store ( string key, mixed var [, int ttl] )
在緩存中保存數據
apc_fetch ( string key )
獲得apc_store保存的緩存內容
apc_delete ( string key )
刪除apc_store保存的內容
完整例子如下:
//apc test 
//constants 
$constants = array('APC_FILE'   => 'apc.php', 'AUTHOR'   => 'tim'); 
apc_define_constants('numbers', $constants); 
apc_load_constants('numbers'); 
echo 'APC_FILE='.APC_FILE.'
'; 
echo 'AUTHOR='.AUTHOR.'
'; 

//variable 
if(!apc_fetch('time1')) apc_store('time1', time()); 
if(!apc_fetch('time2')) apc_store('time2', time(),2); //set ttl 
echo 'time1:'.apc_fetch('time1').'
'; 
echo 'time2:'.apc_fetch('time2').'
'; 

//object 
class a{ 
     function b(){return 'i am b in class a';} 

apc_store('obj',new a()); 
$a = apc_fetch('obj'); 
echo $a->b(); 
echo '
'; 
//array 
$arr = array('a'=>'i am a','b'=>'i am b'); 
apc_store('arr',$arr); 
$apc_arr = apc_fetch('arr'); 
print_r($apc_arr); 
?>
發表時間:2010年6月22日 | 評論 (0) | 全文

PHP 6 的新特性


PHP的下一個版本,V6,包含了很的新特性和語法改進,會使它在面向對像方面性更易用。
其他重要的特性:比如在核心函數中對Unicode (統一編碼)的支持,這意味著 PHP 6提供了更好的更可靠國際支持。

PHP已經很流行,被無數的站點使用,被大部分因特網接入商所支持,被Yahoo這樣的大網絡公司使用著。在即將來臨的PHP版本中準備增加一些成功的新特性,使PHP在某些場合下更易用更安全。你準備好接受 PHP 6 了嗎?如果你明天就升級了,你的程序會運行得很好嗎?你該怎麼辦?這篇文章集合了PHP 6的改變,他們中的一些備份移植到版本的PHP v5.x,您目前的腳本可能需要進行一些調整。

如果你現在使用不是PHP,但是一直在考慮它,考慮一下它的新特性。這些特點,從Unicode的核心支持到XML支持,使它更容易為你寫的功能填補PHP的應用。

PHP 6 新特性

PHP 6當前已經作為開發者快照使用,所以你可以下載和試用一下這篇文章列出很多特性,這些特性已經在當前的快照中實現了。見資源。

改進 Unicode 支持

在PHP的核心函數中,有很多對Unicode 字符串的支持的改進,這些新特性將產生巨大的影響因為它允許PHP為國際字符提供更多的支持。所以如果一個開發者或者架構師使用不同的語言,例如Java程序語言,是因為它具有超過PHP的國際化支持的話,當支持改進時他會花一點時間來考慮一下PHP。

因為今天你已經可以下載到開發者版本的 PHP V6,你將看到一些功能函數已經支持Unicode字符串。有一個函數清單已經被測試和驗證了完全可以處理Unicode,參見資源。

命名空間

命名空間是一種避免因函數或者類之間的命名衝突而使你的函數和類以及方法無法讀取,而不使用前綴命名慣例的一種方法。因此,通過使用命名空間,你可以命名別人可能已經使用的類名,而不用擔心在運行時會出錯。表一提供了一個在PHP中使用命名空間的示例。

您不用在源代碼中做更新或更改,因為你寫的任何PHP代碼可以不包含命名空間而運行得很好。因為命名空間特性似乎會移植到PHP 5.3 X中,如果它可以使用,您可以在自己的程序中引用命名空間。

表一,命名空間示例

namespace NathanAGood;
class XMLWriter
{
// Implementation here...
}

$writer = new NathanAGood::XMLWriter();

?>

 


Web 2.0 特性

依賴於你怎麼使用PHP和你現在腳本的是什麼樣子的,現在的語言和語法差異,可能會或者不會最大程度的影響下面一些特性,這是指那些直接讓你引用的Web 2.0功能到你的PHP應用程序。

SOAP

SOAP是一種網絡服務「說話」的協議,並且支持不少其他語言,例如Java和微軟的.NET,雖然有其他的方法來驅動和使用網絡服務,比如 表象化狀態轉變(Representational State Transfer )REST,SOAP仍然在使不同平台具有可操作性中是最常用的。此外,SOAP在PHP擴展和PEAR庫中使用,SOAP在PHP中默認是不支持的,因此你啟用這個擴展或者叫你的ISP啟用。此外,PEAR包允許你建立SOAP客戶端和服務器,如SOAP包。

如果你改變了默認設置,SOAP將會在PHP 6中啟用。這個擴展將提供你很容易的的實現SOAP客戶端和SOAP服務,允許你編寫的應用提供使用或者網絡服務。

如果SOAP擴展是默認設置,那就意味著你不能在PHP中設置它們,如果您開發的PHP應用程序並且它們發佈到一個ISP服務器上,您可能需要檢查一下你的ISP,以驗證SOAP並啟用為他們升級。

XML

在PHP 5.1中XMLReader 和XMLWriter已經變成PHP核心的一部分,這使你工作起來更輕鬆如果在你的PHP程序中需要使用到XML的話。和SOAP擴展一樣,如果你使用SOAP或者XML這是個好消息因為PHP 6比已經出爐的PHP4 更適合你。

被刪除的東西

除了具有的一些新功能,PHP 6引擎將刪除一些在前面版本中已經有的功能。大部分這些功能,如register_globals 和safe_mode 在目前的PHP中被視為「破的」。因為他們可能會暴露一些安全風險。PHP在努力的清除中,在下一個版本中這些將從PHP中刪除或者廢棄。反對者認為大部分ISP或者企業會保留現在的腳本因為升級到PHP6會破壞現在的的腳本,但是支持者認為很高興看到PHP團隊修補了這些漏洞,並且提供了一個乾淨,安全的運行工具。

將從PHP刪除的功能有:

magic_quotes register_globals register_long_arrays safe_mode

 

發表時間:2010年6月22日 | 評論 (0) | 全文

ie-css3


以前用過一個curved corner 的htc

不知這個寫得如何, 看上去功能不少

http://fetchak.com/ie-css3/
發表時間:2010年5月15日 | 評論 (0) | 全文

Short, Simple and Full guide to install tomcat6 on ubuntu 9.10


寫一下安裝tomcat6 的方法...在ubuntu 的套件中, 人們常常說有問題
剛安裝ubuntu 9.10 的可以試試下面的做法...apt-get 看來沒有出錯

apt-get install tomcat6
apt-get install tomcat6-admin
apt-get install tomcat6-common
apt-get install tomcat6-docs
apt-get install tomcat6-examples
apt-get install tomcat6-user

vi /etc/tomcat6/tomcat-users.xml

<tomcat-users>
<role rolename="admin"/>
<role rolename="manager"/>
<user username="xxx" password="xxx" roles="admin,manager"/>
</tomcat-users>

service tomcat6 restart

Simple enough?

發表時間:2010年3月6日 | 評論 (0) | 全文

這個分類


這個分類究竟會說些甚麼呢?
會教c++ 嗎? 還是javascript呢?

如果想學基本邏輯的話請在google search 一下tutorial 吧...
在這個分類我想要提出一些在程式途中的選擇

甚麼選擇呢?
在下面有一個示範, 也算是第一次的教學吧!

選擇mysql, mysqli 還是PDO?
用不用額外直譯class如adodb?

當中的思路太過複雜, 實在難以完全說明
但我的的想法大約是mysqli 不加class

這是我用四小時在網上翻查資料得出的結論, 當然存在就有其合理性,
要好好理解的話還是要search 看看, 但只要看到mysqli 的優點自然會去用了
不然的話, mysql 加一個輕量的class 也是穩妥的選擇

mysqli:

很重要的, 內置OO用法, 行數比mysql 有一定程度的減少
在虛擬主機中, mysqli 普及性比pdo 高
adodb 等大型框架效率不良
mysql 的procedural function 功能不齊全, 用輕量class 怕團隊做不長, 重量class 效能卻不高, 自製class 浪費時間
pdo 的學習時間遠比mysqli 長而相對優點卻不顯著(好用的功能也不是能大幅節省)

如果是一個大專案, 我支持的當然是mysql + 自訂class, 很多功能如caching 其他都不提供, 而multi query/next 等函式也是不難寫出來的

發表時間:2010年1月24日 | 評論 (0) | 全文