發表文章

目前顯示的是有「php」標籤的文章

ChatGPT可以反編譯?

ChatGPT 好好『善用』,他就是一個好幫手。最近在 台灣駭客年會HITCON CMT 2023第一天的議程中 又看到一種用法-反編譯。 於是拿很久前接觸OPCode時整理的內容作範例試試看。在 之前的文章 中有將一個很簡單的PHP程式利用VLD轉成OPCode,我選用該篇文章中的PHP 5.2.17版本OPCode(如下)嘗試讓 ChatGPT 轉回PHP

Apache NetBeans如何使用Subversion

圖片
由於手上相關系統逐漸更換到PHP 7+,於是也將所使用的IDE更新,升級到 Apache NetBeans 11 以支援PHP 7+的語法。安裝後啟動 Apache NetBeans 11 時總是會看到如上圖的錯誤訊息。 一開始,以為是自己 Subversion 版本太舊(上圖顯示需要 Subversion 1.8以上版本)。但在升級Subversion後狀況依舊…

Disallowed Key Characters發生原因及處理

圖片
如有使用 CodeIgniter Web Framework 的經驗,也許會遇到disallowed key characters錯誤的經驗。會出現這樣的訊息,是因為 CodeIgniter 會檢查client端送來的cookie名稱。 如果先不分析問題發生原因、想馬上解決,可下手調整判斷程式的正規表達式即可

如何使用FreeTDS的TDSDUMP功能debug

有人遇到一個問題,說他的PHP程式連資料庫(MSSQL 2008R2)查詢資料時會因為 Changed database context to 'DATABASE-NAME' 的錯誤而無法執行… "Changed database context to XXXX"這訊息的含意是…登入資料庫所用的帳號,做了切換資料庫的動作。如果登入資料庫的帳號有設定預設使用的資料庫,而程式運作中切換了資料庫。舉例,登入資料庫的帳號預設的資料庫為 DB-A,但程式登入資料庫後切換到 DB-B時,此時資料庫就會回傳這訊息。 雖然這樣的訊息不是『錯誤』,只能算是『資訊』…以往總覺得納悶這為何是錯誤?但,在這次追查問題中使用 SQL Server Profiler 時,發現到真的歸類於error... 總之,個人認為他的程式不可能是因為這的訊息樣而無法運作。且,他PHP程式所在的主機,都已經將錯誤等級設定為超過11才顯示,如下…

HTTP Cookie的限制與網站速度

圖片
cookie 有人遇到一個PHP問題,聽完他的描述後直覺認為是和該系統操作cookie的方式有關,懷疑該系統產生的的Cookie大小超過規範的限制。原以為瀏覽器會呈現Cookie容量過大的錯誤,但是打開瀏覽器的console卻看不到任何錯誤。當時,還誤以為是不是PHP在server端做了處理? 花了冤枉時間後,才知道是因為Firefox不會呈現Cookie超過限制的錯誤,但是Chrome會……昏倒…… 下面範例,是使用PHP產生一個超過RFC規範大小的cookie $value = str_pad("", 5000, "TEST-"); setcookie("TestCookie", $value); 測試環境,分別用以下版本瀏覽器執行上述程式進行測試,並說明結果

STOMP收到Unexpected EOF while reading from socket錯誤

最近在協助處理一個PHP搭配 ActiveMQ 的系統問題,處理過程中習慣性的把所有可能的潛在原因都看一遍。又看到一些以前沒注意過的事情。就稍微記錄一下~ 找問題,自然是先打開log、觀察log中是否有任何的異常。觀察下來,發現偶爾會出現"Unexpected EOF while reading from socket"的錯誤。原以為這樣的錯誤訊息,是出現在 Stomp::readFrame 。沒想到,最後確認是發生於 Stomp::__construct ,程式開啟 ActiveMQ 連線時… 這樣的錯誤、與發生位置,相關性真令人百思不得其解。但無意間,在另一台主機測試時找到了答案~ 在測試連線時,將一樣的程式放到另一台主機上執行、測試時,故意給予錯誤的連線設定。測試結果卻是收到"Unable to connect to 127.0.0.1:61613"的錯誤訊息,和剛剛的不同。 最後找到原因,是因為兩台主機的 PECL :: Package :: stomp 版本不同,整理如下…

PHP無法在$_SERVER內取得自訂header

圖片
最近測試新版PHP時,有人提到他的程式在新的環境執行時無法取得自訂的header。可是,在舊環境執行卻可正常取得該header。 程式是採用$_SERVER取得header。原以為是新版PHP的問題,但查了PHP的版本變更記錄( PHP: Appendices - Manual )卻沒有相關的說明。於是,懷疑和apache有關,傳給PHP的資料就有問題。 此次,除了PHP升級外,Apache也一併升級到2.4。在官方說明- Overview of new features in Apache HTTP Server 2.4 - Apache HTTP Server Version 2. 中提到,Apache 2.4為了增加安全做了以下調整… Translation of headers to environment variables is more strict than before to mitigate some possible cross-site-scripting attacks via header injection. Headers containing invalid characters (including underscores) are now silently dropped. Environment Variables in Apache has some pointers on how to work around broken legacy clients which require such headers. (This affects all modules which use these environment variables.) 依據上述資訊,重新查了有問題的程式。原來,程式中所自訂的header名稱中包含了『_』(底線、underscores)。觸發了Apache 2.4上述的安全加強,PHP就無法在$_SERVER取得header名稱中有底線『_』的header。當然,自訂的header名稱中沒有使用底線『_』的header,是可以正常取得的。 以下,簡單說明問題發生的原因、與相關的狀況,與處理方式…

Codeigniter搭配Apache及PHP-FPM

最近想將使用CodeIgniter這套php framework的系統改用 PHP: FastCGI Process Manager (FPM) 運行。 由於採用了CodeIgnite官方 CodeIgniter URLs : CodeIgniter User Guide 的作法,於網址中移除index.php。因此,當設定好 PHP-FPM 後,尚須處理移除index.php這段設定。 另外,也由於apache的版本演進,不同版本配合 PHP-FPM 的設定方式也有所不同,找資料過程中看過很多種設定。因此把最後採用的設定方式做個紀錄。

php出現Memcached::get(): could not unserialize value, no igbinary support的錯誤

之前一直注意到有個系統的錯誤log中斷斷續續出現如下的錯誤資訊。由錯誤研判,應該是放進memcache的內容有使用 Igbinary 。但是取出時,卻沒做對應的處理。 Severity: Warning --> Memcached::get(): could not unserialize value, no igbinary support /xxx/xxx.php 曾請當時負責維護的苦主同事查看,得到的答案是程式中並沒有使用 igbinary 。 最近在協助查另一個問題時,卻間接找到這個問題發生原因……

cacti如何取得啟用認證機制的redis狀態

去年導入一個新專案時,因考量需要比key:value更複雜的模式,最後捨棄常用的memcache改用redis這套nosql。 和memcache相比,redis無論是功能、相關設定與需要注意的事項都複雜很多。 當初導入redis時,就曾考慮是否需要啟用其認證機制。但只要多花點時間瞭解redis的架構,不經讓人覺得redis的認證機制有點雞肋而暫時不啟用。 畢竟redis是單執行緒(Redis is single threaded),因此無法做延遲的處理。加上redis號稱每秒可處理500k的request,如果有心人士利用暴力法,應該不難打出密碼。 設定的重點,應該是啟動服務時不使用root,並設定好網路環境,避免外部可直接存取、及變更重要指令的名子等等…。 雖然說覺得redis認證機制雞肋,但最後考量能多層保護就多一層保護,最近還是調整設定、與程式,啟用了認證機制。 沒想到,cacti就無法正常取得redis的狀態了……

Memcached::get(): could not uncompress value的錯誤

同事提到一個問題,他的程式到memcache取資料時,都會出現如下的錯誤訊息… Memcached::get(): could not uncompress value 當下的第一個反應,先查看產生資料塞到memcache的程式,是否有開啟壓縮功能? 查過後,確認程式有設定 Memcached::OPT_COMPRESSION 參數,關閉壓縮資料的功能(關掉壓縮功能,是為了和其他不能升級的系統相容 :() 這就神奇了…明明有設定不壓縮,卻還是出現和壓縮有關的錯誤? 抽絲剝繭後,不經懷疑是不是新版的memcache還是會自動壓縮?( memcached 2.0 開始,有不少異動。有興趣可以參考 Changelog for memcached )

codeigniter與MySQL server has gone away

最近在做一個處理,於CLI下程式會下指令給splunk撈取資料,並等候splunk回覆結果。最後再將結果寫入資料庫。當查詢大量的資料時,等待splunk的時間會變長。 原本程式運作很正常,但在我重構程式調整操作DB的方式,以符合線上環境使用後,看log卻發現有時居然會出現了以下的錯誤… A Database Error Occurred Error Number: 2006 MySQL server has gone away 查了一下mysql官方文件,相關資料如下… http://dev.mysql.com/doc/refman/5.0/en/gone-away.html http://dev.mysql.com/doc/refman/5.0/en/error-messages-client.html#error_cr_server_gone_error 看了說明,我遇到的狀況和time out比較相同。和DBA討論、測試後…果然沒錯…就把問題給解決了~ 先說明我做了什麼修改,導致遇到此狀況?

stomp header-content-length對ActiveMQ的影響

不要錢的最貴,最近又遇到一個案例…這次的狀況是,安裝一台新主機,把一些程式搬移到這台新主機。結果,一個連ActiveMQ的程式出了問題。當下看到的狀況是,producer可以將資料送到ActiveMQ,但是資料卻是空白,導致customer無法處理。後續的問題釐清中,確定只有在新主機的producer才會發生此問題,原主機無問題。 新主機上安裝的 pecl-stomp 是1.0.5,舊主機為 pecl-stomp 1.0.3。原以為 pecl-stomp 是否有大改版造成此問題?但,查了change log卻又看不出有重大改變。 所幸,有位精通抓封包的同事比對了新舊主機,相同程式(producer)丟出封包的差異,發現有問題的新主機再丟資料給ActiveMQ時,多了如下的header content-length:15 查了 ActiveMQ-Stomp ,瞭解到content-length對ActiveMQ有特殊的含意。節錄如下…

php如何用正規表達式(Regular Expression)處理unicode

最近使用正規表達式(Regular Expression)處理夾雜中英文、及符號的字串。因為字串是UTF8的編碼,於是翻了一下正規表達式的經典書籍- 精通正規表達式(第三版) (這本書寫的真不錯,看了前兩章就可以感受到作者的用心與功力),看看PHP該如何處理。 書中提到PHP的表示方式為\xnum、\x{num},這和常見的\unum方式不同。照書中所述的處理方式去做,結果和預期不同。 最後看了以下兩篇PHP官網上的說明,才瞭解正確的用法 Pattern Modifiersu ,提到PCRE UTF-8 mode… This modifier turns on additional functionality of PCRE that is incompatible with Perl. Pattern strings are treated as UTF-8. This modifier is available from PHP 4.1.0 or greater on Unix and from PHP 4.2.3 on win32. UTF-8 validity of the pattern is checked since PHP 4.3.5. Escape sequences ,這篇說明了 \xYY 和 \x{YYYY}的差異… After "\x", up to two hexadecimal digits are read (letters can be in upper or lower case). In UTF-8 mode, "\x{...}" is allowed, where the contents of the braces is a string of hexadecimal digits. It is interpreted as a UTF-8 character whose code number is the given hexadecimal number. The original hexadecimal escape sequence, \xhh, matches a two-byte UTF-8 character if the value is greater t...

不同版本的php,其Opcode是否不同?

PHP 5.4 出來快半年了,最近才注意到一些套件似乎還沒完全跟上,舉三個有在用的extension為例… 看來,跟核心比較無關的stomp已經支援PHP 5.4(stable)。另外兩個和核心有關的,尚在beta… APC(Alternative PHP Cache),目前版本為 APC 3.1.13 。 3.1.0 開始支援 PHP 5.4,目前尚為beta VLD(Vulcan Logic Disassembler),目前版本為 0.11.1 。 0.11.0 開始支援 PHP 5.4,目前尚為beta Stomp client extension,目前版本為 1.0.4 。 已經支援 PHP 5.4,並stable 不經也好奇PHP版本不同時,編譯出來的 Opcode 是否相同?於是用下面『簡單』的php程式作個小測試…

PHP的query timeout對於lock中的tbale是否有效

之前有介紹過 如何設定 sybase 的 lock timeout ,將FreeTDS更新到0.91後,順便測試當資料庫發生鎖定時,query timeout是否能夠強制程式中斷,程式不會因此卡住?依舊同時測試MS SQL、及Sybase。 測試的假設狀況為…刻意將測試用table產生lock,同時以php程式去查詢已經被lock的table,該主機上使用FreeTDS 0.91,並且設定了query timeout為五秒(請參考 php存取mssql、sybase時,如何設定query timeout )。 測試的結果…FreeTDS果然對於這兩家資料庫的處理不同… MS SQL:查詢超過五秒後,查詢被中斷,控制權回到程式(不需設定lock timeout) Sybase:查詢超過五秒後,程式依舊卡住。(除非將lock的table解除lock,或設定lock timeout。控制權才會回到程式) 當然, FreeTDS 對於MS SQL的處理行為,是比較符合預期的… 在測試過程中,無意間發現一個現象…

php存取mssql、sybase時,如何設定query timeout

以前在整理 php.ini 、及 freetds.conf 的設定時,注意到兩者都有支援(query)timeout、及connect timeout,當時也作了設定。但最近的一些狀況,讓我好奇(query)timeout設定是否真的有發揮效果? 由於 FreeTDS 可以支援MS SQL、Sybase(FreeTDS is a set of libraries for Unix and Linux that allows your programs to natively talk to Microsoft SQL Server and Sybase databases.),所以就一併測試這兩種資料庫。首先,看一下相關設定的說明,php.ini 中對於MS SQL、Sybase的設定、及freetds的設定,分別如下… MS SQL Server configuration options ,提到mssql.timeout、mssql.connect_timeout這兩個參數 Sybase configuration options ,提到sybct.login_timeout、sybct.timeout這兩個參數 freetds.conf ,則提到(query)timeout、及connect timeout這兩個參數 測試的結果,無論是MS SQL、Sybase的timeout居然都沒效果。 難道又是文件和實際不符合嘛?找了些資料,看到 Bug #34647 mssql.timeout has no affect 中的討論、說明後,去挖出freetds change log,終於有點眉目。原來是因為我所使用的FreeTDS版本太舊,timeout機制在FreeTDS v8.2( freetds v0.82 change log )才開始支援。

firefox處理cookie的問題

圖片
之前在研究HTTP時,瞭解到各家瀏覽器在實作HTTP時其實並不相同。最近的一個奇怪案例,最後找出的原因…居然是因為瀏覽器對於cookie處理不同~ 為了解釋,假設一下案例 現在時間是 2012/6/1 11:00 主機時間是 2012/6/1 03:00(主機的時間慢了八小時) cookie expire time為六小時 當server端的程式產生一個cookie,cookie expire time為六小時。於是,程式取得主機時間2012/6/1 03:00,加上expire time 六小時候,這個cookie將在2012/6/1 09:00 逾期。 此時,client端的時間是2012/6/1 11:00。因此,當瀏覽器收到這個cookie時,對瀏覽器而言,理論上已經超過了逾期時間(2012/6/1 09:00)三小時。不幸的是…各家瀏覽器的結果不同… 測試了Firefox、IE、Chrome、safari這四家瀏覽器後。只有Firefox的行為不同,居然會繼續使用這個已經逾期的cookie。 為了測試的方便,我將cookie expire time 設定為一分鐘。下圖,則是以VM作測試的結果…

PHP如何做出影像銳利化效果

圖片
一般來說,當我們將圖檔縮小SIZE後,圖檔多少會有點模糊。以我用影像處理軟體在處理MSN的圖案來說,每次將照片縮成96x96後,總是會再利用像處理軟體做銳利化處理。讓縮小後的照片看起來比較清晰。 現在的網站,充斥者大量的圖片。為了頁面上整體性、或美觀,多少也會運用到即時縮小圖檔的功能。最近剛好在協助處理這類的事情,看者頁面上排者縮小後的圖檔,真是不習慣這些糊糊的圖片…不經想提升縮小後圖檔的品質… 當圖檔縮小後,怎麼使用PHP做出銳利化效果,讓縮小後的圖變的清楚呢?找了一下 php GD 文件,並測試了一下。 我以 浮在雲海上的台北101 的圖做為範例。將原圖分別做兩種處理。一個是僅做縮圖(下圖右側)、另一個是縮圖並銳利化(下圖左側)。執行的結果如下…效果還不錯… >>點此看大圖 ,比較容易看出差異。

CodeIgniter的Connecting to Multiple Databases,是否會造成大量連線數?

最近有人問了一個關於 CodeIgniter 的資料庫連線問題。問題是,當一個controller執行時,可能呼叫多的model。如果這些model在開資料庫連線時,全都採用"Connecting to Multiple Databases"的方式,豈不是一個網頁就會產生多個資料庫連線? CI採用singleton pattern。但"Connecting to Multiple Databases"的模式,卻是return instance。所以,這個疑問是有可能發生的。於是測試了一下… 做了一個小實驗。寫一個controller,他會呼叫三個不同的model。這三個model都採用"Connecting to Multiple Databases"方式,都連到同一台資料庫。如此,該資料庫上是不是就會有三個連線? 用var_dump()看每個連線,果然每個連線的resoure id都不同(共三個)。但直接在資料庫上看連線數,卻只有一個。這樣的結果蠻奇怪的。想了一下,原來是和php開啟資料庫處理方式有關。 我這次測試,使用兩種資料庫-Sybase、MSSql。兩者的狀況分別如下…