2017年10月8日 星期日

在 Windows Server 2003 安裝 PHP 5.6.24

在微軟的支持下,PHP 可以在 Windows 的平台上,順利且有效率的運作。其中,包括 fastcgi、sqlsrv、及 wincache 等,是由微軟所支持提供的。

但我個人猜測,也是在微軟的干預下,以 Windows Server 2003 及 Windows XP 推出已超過 10 年為理由,決定從 PHP 5.5 開始,不再支持這兩個 OS。因此在這兩個廣泛使用的 OS 上,就無法安裝執行新版的 PHP,只能繼續堅守 PHP 5.4 以前的版本了。

Windows Server 2003,和 2008 以後的 OS 比起來,只需要較小的硬碟空間,在 VM 上安裝執行,非常據有優勢。因此,直到目前 (2017年) 我們還是繼續堅守著 2003。

每過一段時間,我就會在網路上搜尋,是否有在 Windows Server 2003 安裝 PHP 5.6 的可能性。直到最近,才在 Stack Overflow 上找到一段問答,How to install PHP 5.5 on WinXp 。在這討論裡,也是常見的,已經停止支援等等的話,但有一小段不小心就會遺漏的留言
But there is an unofficial build of PHP 5.6 at http://www.apachelounge.com/viewtopic.php?t=6334
這真是讓人興奮的話。到這時才知道,已有人重新修補編譯 PHP 5.6.4,讓它可以在 2003/XP 上執行,雖然,特別提醒的那一句話 "Play with it, do not use in in production ... " 讓人很不安心,但終究是有了可能性。

後來,在 github 上,也找到有人說明修補和編譯的作法,ProgerXP/php-5.6-xp。也照著做了,不過,後來搞清楚那是針對 Apache 的作法,也就是編出來是 thread-safe 的執行檔。但是,在 cgi 模式下,要用 non-thread-safe 的作法,才能有較好的效率,因此,也就放棄了。

很幸運的,後來找到一個中文的網頁,PHP 7 and PHP 5.6 for Windows XP/2003。它只是建立了一個 nonxp.dll,再修改 exe 和 dll 的相關資訊,讓它可以在 2003/XP 上執行。

雖然,它也改了 PHP 7.0,讓它可以在 2003/XP 上執行,但是可以使用的 sqlsrv driver 只有到 PHP 5.6,請參考 Unofficial Microsoft SQL Server Driver for PHP (sqlsrv),所以,我只有使用 PHP 5.6 這個版本。安裝後,稍微比較了一下效能,PHP 5.6 的效能大約是 PHP 5.4 的兩倍,的確很吸引人。

目前,我在其中一部 Windows 2003 的伺服器上,使用修改過的 PHP 5.6.24,等一段時間後,確認沒有問題,再全面改用。有空,也要看一下 nonxp 的原始碼,針對用到其中的function 的功能,加以測試,以確認一切是正常的,用起來才會安心。

GitHub 上的原始碼

在取得 nonxp.dll 的原作者的同意後,已將 nonxp.dll 及 補丁工具的程式上傳 github: php-5.6-xp-2003。

碰到的錯誤

採用 nonxp.dll 的作法,版本 PHP-5.6.24,使用 fastcgi 模式,送出 header('Content-Type: application/javascript'); 時,會產生 IIS 500 的錯誤。但是,讓人懊惱的是,有時會連續出錯,有時又很正常。對了,只要動到 Laravel 5.0 的 routes.php,就會一直出錯,這個檔到底用到了什麼功能,以致於如此? 再試用 Apache Lounge 的討論區的 Jan-E 所改的 PHP-5.6.4,一樣也會有此問題。再切回 PHP 5.4 就完全沒問題。

後來猜測可能是 Laravel 5.0 中的某些部分,在 PHP-5.6.24 下,會出錯。例如 nette/tracy
在 PHP 5.4 和 Laravel 5.0 下,可以安裝,但不能正常運作。

再次測試,把應用程式,搬到 Laravel 5.1 下,看起來,能正常運作,不會一直出現 IIS 500 的錯誤,再持續觀察吧。

2017年10月1日 星期日

Slim 2 筆記

Middleware、Hook 的呼叫順序

Middleware, before next->call()
Hook slim.before
Hook slim.before.router
Hook slim.before.dispatch
-------------------------------------
response body render
echo 的內容會寫入 output buffer
-------------------------------------
Hook Middleware, after next->call()
Hook slim.after.dispatch
Hook slim.after.router
Hook slim.after

2017年9月29日 星期五

PHP 7 and PHP 5.6 for Windows XP/2003

Original page: http://www.lindasc.com/php/  (Here is just a translation.)
PHP Version: 7.0.9 / 5.6.24
Updated: 2016-7-28
Supported OS: Windows XP/2003
Description:
  Instead of patching and rebuilding the whole PHP completely, which is a complicated work, this work implements the API functions that are only available after Vista and then patches the import descriptors of the executable files.
  The implemented functions are listed as follows.

DLL file function name ver. of nonxp.dll
iphlpapi.dll if_nametoindex 0.0.1.11
kernel32.dll GetFinalPathNameByHandleA 0.0.2.20
GetFinalPathNameByHandleW 0.0.2.20
GetTickCount64 0.0.1.11
InitializeConditionVariable 0.0.4.40
InitializeCriticalSectionEx 0.0.3.30
SleepConditionVariableCS 0.0.4.40
WakeAllConditionVariable 0.0.4.40
WakeConditionVariable 0.0.4.40
shell32.dll SHGetKnownFolderPath 0.0.3.30
ws2_32.dll WSASendMsg 0.0.1.11
inet_ntop 0.0.1.11
inet_pton 0.0.1.11

  Instructions of installation:
  PHP 7: the OS must install IE8 and VC14 redistributable package.
      PHP 5.6: the OS must install IE8 and VC11 redistributable package.
  Download links:
Source code
Source code of nonxp.dll
The source code of nonxp.dll and the patch tool have been uploaded to github, php-5.6-xp-2003, according to the permission of the original author.

2017年9月20日 星期三

Slim 2 與 Laravel 5.0,小比一下

使用 Laravel 一陣子了,好像只用到其中一小部分,如 Query builder、Request、View 等。然後,可以使用 Composer 將一些東西包進 Slim,程式就可以跑了。

環境是 Windwos server 2003+fast-cgi,PHP 為 PHP 5.4.45+wincache 及 PHP 5.6.24+opcache。

 $ ab -n 100 -c 4 http://10.161.81.188/test/sdic_qry/index.php/sql_qry?dep=P020

hello-world,只是單純送出 "Hello, world!" 的字串,用來測試空的 framework 的性能。Slim 2 有加裝一些 package,也設定一些習慣使用的 Laravel 的靜態介面。

sql_qry 則進行資料庫的 query,用以測試資料庫存取的影響。其中,後端資料庫為安裝在 VM 的 SQL 2000 server。

PHP 5.6.24

Slim 2,debug off,hello-world,,Requests per second:    189.16 [#/sec]
Slim 2,debug on,hello-world,Requests per second:    187.35 [#/sec] (mean)
Slim 2,debug off,sql_qry,Requests per second:    143.17 [#/sec] (mean)
Slim 2,debug on,sql_qry,Requests per second:    129.30 [#/sec] (mean)

Slim 3,debug on,hello-world,Requests per second:    143.44 [#/sec] (mean)
Slim 3,debug off,sql_qry,Requests per second:    118.56 [#/sec] (mean)

Laravel 5.0,hello-world, 66.33 [#/sec] (mean)
Laravel 5.0,sql_qry,5.6.24,Requests per second:    55.74 [#/sec] (mean)

Slim 2,debug off,laravel-session (file/database),Requests per second:    60 [#/sec] (mean)

PHP 5.4.45

Slim 2,debug on,hello-world,Requests per second:    80.37 [#/sec] (mean)
Slim 2,debug off,hello-world,Requests per second:    110.83 [#/sec] (mean)
Slim 2,debug off,sql_qry,Requests per second:    87.60 [#/sec] (mean)
Slim 2,debug on,sql_qry,Requests per second:    72.85 [#/sec] (mean)
L5,sql_qry,5.6.24,Requests per second:    25.22 [#/sec] (mean)
L5,hello-world, 29.75 [#/sec] (mean)

測試中,Tracy/Debuger 會造成 Failed requests。
在 Slim 2 中,加上 Laravel 的 session 後,效能降到和 Laravel 差不多。
其中,session 的垃圾收集,會大幅的拖慢效能。垃圾收集的時機,由設定中的 'lottery' => [2, 100] 來決定,此代表 50 次,會做一次垃圾收集。減少垃圾收集的機率,可提升效能。
請參考 PHP Session Garbage Collection: The unknown performance bottleneck
所以,是否使用 Laravel 的 session,會是一個決擇。然而,其可以選擇不同的 drvier,實在是非常方便的作法。

以下為使用下列指令測試的結果

$ ab -n 100 -c 10 http://10.161.81.188/test/sdic_qry/index.php/cou_cur/introduction?cur=P020

Slim 2 的結果如下

Server Software:        Microsoft-IIS/6.0
Server Hostname:        10.161.81.188
Server Port:            80

Document Path:          /test/sdic_qry/index.php/cou_cur/introduction?cur=P020
Document Length:        18064 bytes

Concurrency Level:      10
Time taken for tests:   1.373 seconds
Complete requests:      100
Failed requests:        26
   (Connect: 0, Receive: 0, Length: 26, Exceptions: 0)
Write errors:           0
Total transferred:      1829852 bytes
HTML transferred:       1806452 bytes
Requests per second:    72.85 [#/sec] (mean)
Time per request:       137.275 [ms] (mean)
Time per request:       13.727 [ms] (mean, across all concurrent requests)
Transfer rate:          1301.74 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.7      0       4
Processing:    52  129  41.4    119     330
Waiting:       50  128  41.4    118     329
Total:         52  130  41.5    120     331

Percentage of the requests served within a certain time (ms)
  50%    120
  66%    131
  75%    140
  80%    145
  90%    178
  95%    206
  98%    308
  99%    331
 100%    331 (longest request)

Laravel 5.0 的結果如下

Server Software:        Microsoft-IIS/6.0
Server Hostname:        10.161.81.188
Server Port:            80

Document Path:          /test/sdic_for_reg/index.php/cou_cur?cur=P020
Document Length:        14987 bytes

Concurrency Level:      10
Time taken for tests:   3.927 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      1606344 bytes
HTML transferred:       1498700 bytes
Requests per second:    25.46 [#/sec] (mean)
Time per request:       392.702 [ms] (mean)
Time per request:       39.270 [ms] (mean, across all concurrent requests)
Transfer rate:          399.46 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   1.1      0       5
Processing:   146  372  95.2    346     738
Waiting:      143  370  95.0    345     737
Total:        147  373  95.4    347     739

Percentage of the requests served within a certain time (ms)
  50%    347
  66%    400
  75%    436
  80%    463
  90%    495
  95%    527
  98%    626
  99%    739
 100%    739 (longest request)

結果是 Slim 2 大概是 Laravel 5.0 的 3 倍。然後,隨著程式成長,使用 Slim 的環境,也由每秒完成的 request 也由 72 個降到 65 個左右。

再 Optimizing Composer's autoloader 一下,指令 composer  dumpautoload -o,又稍微提升到每秒完成 75 個 request。

2018-01-29 測試

應用程式的條件,使用 Laravel 的 DB 和 View,關掉 debug。在 optimize 以前,大約 100 [#/sec],optimize 後,約 118 [#/sec]。
不過,結果不是很穩定,後來再測,降到約 70 [#/sec]。

使用 ApacheBench (ab) 測 Slim 變得很慢

參考 HTTP, Slim and ApacheBench

使用 Apache 伺服器跑 Slim 時,用 ab 測效能,會變得很慢,一秒才處理一個 request。
這是因為 ab 送出 HTTP/1.0 的 request,它會等伺服器關閉 connection。可是 Slim 卻回應 HTTP/1.1 的 header,因此雙方在互相等待連線關閉。

解決辦法,針對所有的 HTTP/1.0 或沒有 Connection header 的 request,都送出 "Connection: close" 。在 Slim 初始化後,加上下面的程式碼。

if ($_SERVER['SERVER_PROTOCOL'] == 'HTTP/1.0' && 
   empty($_SERVER['HTTP_CONNECTION'])
) {
    // header('Connection: close');
    $app->response->headers->set('Connection', 'close');
}


2017年9月18日 星期一

透過 WINE 安裝 FileZilla ftp server (失敗)

因為想把一些在 Windows 2003 server 上跑的服務,移到 docker 的虛擬平台上,所以想透過 WINE 安裝 FileZilla ftp server。先說測試結果 -- 失敗,雖然離成功只剩一小步,但可能無法跨越。

起先在 docker 下執行 WINE,參考 suchja/wine 的作法。
在 docker host 上,不需安裝 X window,使用 suchja/x11server 來當圖形界面輸出。
docker run -d --name display -e VNC_PASSWORD=newPW -p 5900:5900 suchja/x11server

然後啟動  Wine container,如下:
docker run --rm -it --link display:xserver --volumes-from display suchja/wine:latest /bin/bash

啟動 container 後,啟始 wine
wine wineboot --init

下載安裝檔
curl http://xxx.com/yyy/FileZilla_Server-0_9_43.exe -o FileZilla_Server-0_9_43.exe
XP 支援的版本,只到 0.9.43。

安裝,在便令視窗下指令,然後,要透過 vnc client 連上 server,操作圖形視窗。
wine FileZilla_Server-0_9_43.exe

注意,安裝時,需要 root 的身分,才能開啟 port,ftp server才能啟動。在上述指令,不要加上 --rm 的選項,離開 container 的互動介面後,將此 container 存成 image。
docker commit f26355b23ac6 wine-filezilla-server

使用新的 image 啟動 container,使用下列指令啟動 ftp server,以及進入管理界面。
wine FileZilla\ Server.exe /compat /start &
wine FileZilla\ Server\ Interface.exe &

管理界面,有點怪怪的,右側 acount list 不會出現,按一下左邊的 item,就會出現。可以建立帳號,但指定目錄,有點不太行。

建好帳號後,用 client 端登入,可以登入,但是讀資料失敗,ls -aL 無法成功。
"503 Bad sequence of commands" 的錯誤,推測 wine 不適合執行網路伺服器的程式。

以上,記錄安裝測試的大致過程,供做參考。

2017年9月12日 星期二

ThinkPad Trackpoint 設定



$xinput
⎡ Virtual core pointer                     id=2 [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer               id=4 [slave  pointer  (2)]
⎜   ↳ Logitech USB Receiver                   id=12 [slave  pointer  (2)]
⎜   ↳ Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint id=8 [slave  pointer  (2)]
⎣ Virtual core keyboard                   id=3 [master keyboard (2)]
    ↳ Virtual core XTEST keyboard             id=5 [slave  keyboard (3)]
    ↳ Power Button                             id=6 [slave  keyboard (3)]
    ↳ Power Button                             id=7 [slave  keyboard (3)]
    ↳ Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint id=9 [slave  keyboard (3)]
    ↳ Logitech USB Receiver                   id=13 [slave  keyboard (3)]

$xinput list-props "pointer:Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint"
Device 'Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint':
Device Enabled (152): 1
Coordinate Transformation Matrix (154): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
Device Accel Profile (413): 0
Device Accel Constant Deceleration (414): 1.000000
Device Accel Adaptive Deceleration (415): 1.000000
Device Accel Velocity Scaling (416): 10.000000
Device Product ID (271): 6127, 24585
Device Node (272): "/dev/input/event14"
Evdev Axis Inversion (417): 0, 0
Evdev Axes Swap (419): 0
Axis Labels (420): "Rel X" (162), "Rel Y" (163)
Button Labels (421): "Button Left" (155), "Button Middle" (156), "Button Right" (157), "Button Wheel Up" (158), "Button Wheel Down" (159), "Button Horiz Wheel Left" (160), "Button Horiz Wheel Right" (161), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412)
Evdev Scrolling Distance (422): 0, 0, 0
Evdev Middle Button Emulation (423): 0
Evdev Middle Button Timeout (424): 50
Evdev Middle Button Button (425): 2
Evdev Third Button Emulation (426): 0
Evdev Third Button Emulation Timeout (427): 1000
Evdev Third Button Emulation Button (428): 3
Evdev Third Button Emulation Threshold (429): 20
Evdev Wheel Emulation (430): 0
Evdev Wheel Emulation Axes (431): 0, 0, 4, 5
Evdev Wheel Emulation Inertia (432): 10
Evdev Wheel Emulation Timeout (433): 200
Evdev Wheel Emulation Button (434): 4
Evdev Drag Lock Buttons (435): 0

$xinput set-prop "pointer:Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint" "Evdev Wheel Emulation" 1
$ xinput set-prop "pointer:Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint" "Evdev Wheel Emulation Button" 2
$ xinput set-prop "pointer:Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint" "Evdev Wheel Emulation Timeout" 200


The need for the "--with-bdeps y" and "--backtrack 100" switches will go away over upcoming



2017年9月9日 星期六

使用 docker 安裝及執行 Laravel

因為環境的關係,例如,在 Windows server 2003 下,只能跑 PHP 5.4,就限制了只能使用Laravel 5.0。而要裝 Laravel 5.0,也必需使用 PHP 5.4 ~ 5.6 的版本來安裝。相對的,使用 CentOS,則能使用最新版本的 PHP,相對的,也必須使用較高版本的 Laravel。

可是,自己個人使用的電腦,一定不想要同時安裝各種版本的 PHP,通常也不允許。甚至,像 PHP 5.4,因為官方不再支援,有可能無法安裝。在這種情形下,docker 實在是一個很理想的環境或工具。在這裡,要安裝 Laravel 5.0,選擇使用的 image 是 composer/composer:php5-alpine,它用的是 PHP 5.6,雖然標註為 DEPRECATED,但還是能用的。

我是習慣在一個專用的目錄下,放置和 Laravel 相關的專案,因此,將 composer 的 cache 也放在此目錄下,就可以省下很多等待下載的時間。其中 "-v $(pwd)/cache:/composer" 的選項,就是指定存放 cache 的 volume。

在建立專案時,會在該目錄下建立一個新的目錄,因此用 "-v $(pwd):/app" 來指定 volume。但是 update 時,則需在該專案的目錄下,因此 volume 的指定便成為 "-v $(pwd)/la-50:/app",而不用真的切換目錄。

$ docker run --rm -v $(pwd):/app  -v /cache:/composer composer/composer:php5-alpine create-project laravel/laravel la-50 "5.0.*" --prefer-dist

# 移險 la-50/vendor/compiled.php 後,進行 update
$ cd la-50
$ rm vendor/compiled.php

$ docker run --rm -v $(pwd):/app  -v ~/php-projects/cache:/composer composer/composer:php5-alpine update

接著用 PHP 5.4 來執行測試。注意,這裡使用的 image 已安裝所需的 PHP extension 了。
docker run -it --rm -v $(pwd):/app -p 8000:8000 php54_app php /app/artisan --host=0.0.0.0 serv

然後,使用瀏覽器開啟 http://localhost:8000/ 即可看到結果。













網誌存檔