Joe Horn 的啟示錄
Joe Horn's Blog
  • LinkedIn
  • Facebook
  • Instagram
  • GitHub
  • Docker Hub
RSS
  • VPS Referrals
  • My Plurk
  • My Plurk Bot

9 月 8 2010

PHP 讓人詬病的系統安全性

這篇討論的不是 PHP Web 的安全相關議題,而是 Web server 管理者應該考量的系統安全議題。XSS、SQL injection 屬於前者,防禦的對象是網頁的瀏覽者;而這篇討論的防禦對象是經常被忽略的 PHP 網頁系統開發人員。

很多人都知道,PHP 屬直譯語言。因為不需要編譯,所以程式碼幾乎可以說是裸露的;除非用 ionCube PHP Encoder 這類的產品作加密,否則,開發人員只要有程式檔案的存取權,就可以看到程式碼。
現今,幾乎所有的 PHP 網頁系統都使用了後端資料庫,而資料庫存取的設定也都是寫在 PHP 程式碼裡面,類似以下這樣:

define( 'DB_SERVER' ,		'localhost' );
define( 'DB_SERVER_USERNAME' ,	'db_username' );
define( 'DB_SERVER_PASSWORD' ,	'db_password' );
define( 'DB_DATABASE' ,		'db_name' );

再透過 require()、require_once()、incluce()、include_once() 等設定檔引入。
如果這個設定檔的路徑沒有在 include_path 系統變數中,引入的方法大概會是這樣:

require_once( '/SOME/WHERE/DB_SETTING.php' );

這樣的系統意味著,有心的程式開發人員可以透過以下這一行程式,輕易取得資料庫存取設定:

echo file_get_contents( '/SOME/WHERE/DB_SETTING.php' );

若是 /SOME/WHERE 被放入 include_path 系統變數,程式開發人員可以透過以下的程式碼引入資料庫存取設定:

require_once( 'DB_SETTING.php' );

雖然以下的程式碼已經無法取出資料庫存取設定:

echo file_get_contents( 'DB_SETTING.php' );

但遇到以下這種程式碼依然是破功:

$paths = explode( ':' , ini_get( 'include_path' ) );

foreach ( $paths as $path ) {
  $file_str = $path . DIRECTORY_SEPARATOR . 'DB_SETTING.php';

  if ( file_exists( $file_str ) ) {
    echo file_get_contents( $file_str );
  }
}

即使設定 auto_prepend_file(之前的文章有提過),或是採用 Autoloading classes,這種問題依然存在。

根本的解決方法就是用 ionCube PHP Encoder 這類的產品作加密,或是用 C 語言撰寫 PHP extension。
很無奈.. 但卻是一針見效。 :-P

By Joe Horn • PHP, Thoughts 0 • Tags: PHP, security

8 月 25 2010

PHP 的 mysqlnd(MySQL Native Driver)

PHP 自 5.3.0 開始,引入 mysqlnd 這個 extension。
在 5.3.0 的 Full ChangeLog 中可以看到這行:

Added mysqlnd extension as replacement for libmysql for ext/mysql, mysqli and PDO_mysql. (Andrey, Johannes, Ulf)

依照個人的過往經驗,native driver 的效能都會比較好,而 mysqlnd 也不例外(有興趣的可以看看這篇文章)。

比較可惜的是,mysqlnd 在 Windows 平台的 PHP 是預設套件;在 *NIX 平台,使用前必須在編譯前就先做好設定(configure;參數可參考 PHP 官方的mysqlnd 安裝文件)。

剛才,很高興看到 FreeBSD 的 PHP5 ports 加入了 option,讓我們可以輕鬆搞定。 8-)

By Joe Horn • Database, FreeBSD, PHP 0 • Tags: FreeBSD, MySQL, mysqlnd, PHP

8 月 13 2010

別再瀏覽「看看誰把你從 MSN 聯繫名單中刪除了」這種網站了

剛剛在 WLM(原稱 MSN)收到這種訊息:

###### 說:
看看誰把妳從他的MSN聯繫名單中刪除了。
http://www.#######chat.info?mid=13868233133262797975

心血來潮上來貼這篇文章。

這種訊息應該不少人都收過,這種網站也應該有很多人看過。
我無法理解的是,當一個陌生的網站要你輸入你在其他網站或軟體的帳號密碼時,你怎麼能安心的輸入?
你能保證這個網站不會紀錄你輸入的密碼,用你的帳號密碼為非作歹?

這樣還不懂的話,我舉個生活化一點的例子:

陌生人:「我能幫你查你在XX證券開立的帳戶裡目前總值是多少哦!」
網站標題:「我能幫你查看看有誰把你從 MSN 聯繫名單中刪除了哦!」

你:好啊好啊!我想知道!怎麼查?
陌生人:只要給我你的帳戶的帳號跟密碼,我就可以幫你查。
網站內容:「請輸入你的帳號跟密碼,我就可以幫你查!」

假如真的有陌生人這麼跟你說,你會給他帳號跟密碼嗎?
醒醒吧!=_=b

如果你已經把帳號密碼送給某個(或是某些)網站的話,就… 快點變更密碼吧。
如果你收到朋友傳送類似的訊息,或是怪怪的網站給你的話,請回訊給對方,提醒對方變更密碼,甚至是檢查電腦是否中毒。

By Joe Horn • Life, Thoughts 0 • Tags: MSN, security, Windows Live Messenger, WLM

8 月 8 2010

[PHP] 試玩 MongoDB 的資料關聯

發現 MongoDB 是好一陣子前的事,而我也在某台機器上把它裝起來。
之前玩的時候,發現 MongoDB 不須帳號與密碼就可以連接,而且也無法配置使用者權限,所以把它丟在旁邊。

前幾天,我在網路上看到網友詢問 MongoDB 有沒有辦法作 JOIN,而他得到的答案是否定的。
趁著今天在家閒閒沒事作,書也看完幾個段落,就透過 PHP 來試試這種 ODBMS 如何實作資料關聯。

MongoDB 與常見的資料庫(例如:MySQL)有些微的不同:

資料庫資料表
MongoDB 稱之為Database(DB)Collection
MySQL 稱之為Database(DB)Table

先把這個觀念講清楚,底下的範例程式碼才不會看得霧煞煞。 8-)

首先,先建立 DB 與 Collection:

// 連接 MongoDB
$m = new Mongo();

// 連接資料庫,名稱就是 test
$testDB = $m->selectDB( 'test' );

// 建立 Collection,名稱分別是 user 與 sex
$testDB->createCollection( 'user' );
$testDB->createCollection( 'sex' );
  • MongoDB 沒有 createDB 這種指令。只要選擇資料庫,建立 Collection 之後,系統就會自動產生 DB。
  • 指令列模式下,選擇資料庫的指令跟 MySQL 相同(USE DB_NAME)。

再來,存入性別資料:

// 連接 MongoDB
$m = new Mongo();

// 連接資料庫,名稱就是 test
$testDB = $m->selectDB( 'test' );

// 在 sex 這個 Collection 裡面放入資料,好讓程式分辨男性與女性
$testDB->sex->insert( array('sex_name' => 'Female') );
$testDB->sex->insert( array('sex_name' => 'Male') );

// 把 sex 這個 Collection 的資料倒出來看
$cursor = $testDB->sex->find();
$array = iterator_to_array($cursor);
var_dump($array);
  • 以往我們儲存在 Table 的 data row 會有個 id 值,方便我們建立關聯。MongoDB 這種資料庫則是在 Collection 裡面放物件,可以不需要 id 值。

開始存入使用者名稱,並紀錄他(她)們的性別:

// 連接 MongoDB
$m = new Mongo();

// 連接資料庫,名稱就是 test
$testDB = $m->selectDB( 'test' );

// 找出男性資料,並取得關聯值
$male = $testDB->sex->findOne( array('sex_name' => 'Male') );
$refMale = $testDB->sex->createDBRef( $male );

// 找出女性資料,並取得關聯值
$female = $testDB->sex->findOne( array('sex_name' => 'Female') );
$refFemale = $testDB->sex->createDBRef( $female );

// 存入使用者資料
$testDB->user->insert( array('name' => 'BoyName', 'sex' => $refMale) );
$testDB->user->insert( array('name' => 'GirlName', 'sex' => $refFemale) );

// 取出並顯示使用者資料
$cursor = $testDB->user->find();
$array = iterator_to_array($cursor);
foreach ( $array as $user ) {
        // 找出性別的關聯物件
        $sexRef = $testDB->user->getDBRef($user['sex']);
        echo "Name: {$user['name']}\tSex: {$sexRef['sex_name']}\n";
}

以上,簡單的試玩心得。 (羞)

By Joe Horn • Database, PHP 0 • Tags: Database, MongoDB, Object, ODBMS, PHP

7 月 14 2010

PHP 的內建常數

昨晚在 PTT 的 PHP 板回了一篇文章,提到 PHP 的內建常數;現在來分享一下,順便作個紀錄,方便日後查詢。

PHP 有不少實用的內建常數,方便我們寫程式時直接呼叫。
有興趣研究的人,可以看看這個網頁,或是用 get_defined_constants() 把內建常數全部倒進陣列,再用 var_dump() 或 print_r() 顯示。

下表列出一些我覺得常用的內建常數,範例值來自 64 位元版本的 FreeBSD ports 安裝之 PHP 5.3.2:

常數名稱常數型態範例值或說明可用版本
PHP_VERSIONstring“5.3.2”無限制
PHP_MAJOR_VERSIONinteger55.2.7+
PHP_MINOR_VERSIONinteger35.2.7+
PHP_RELEASE_VERSIONinteger25.2.7+
PHP_EXTRA_VERSIONstring“”5.2.7+
PHP_OSstring“FreeBSD”無限制
PHP_PREFIXstring“/usr/local”4.3.0+
PHP_BINDIRstring“/usr/local/bin”無限制
PHP_LIBDIRstring“/usr/local/lib/php”無限制
PHP_DATADIRstring“${prefix}/share”無限制
PHP_SYSCONFDIRstring“/usr/local/etc”無限制
PHP_LOCALSTATEDIRstring“/usr/local/var”無限制
PHP_CONFIG_FILE_PATHstring“/usr/local/etc”無限制
PHP_CONFIG_FILE_SCAN_DIRstring“/usr/local/etc/php”無限制
PHP_SHLIB_SUFFIXstring“so”4.3.0+
PHP_EOLstring此變數可用來判斷 “\n”、”\r”、”\r\n”(三個通吃,超好用)。4.3.0+
PHP_MAXPATHLENinteger10245.3.0+
PHP_INT_MAXinteger92233720368547758074.0.4+ 與 5.0.5+
DATE_COOKIEstring “l, d-M-y H:i:s T”
輸出範例:
Wednesday, 14-Jul-10 20:25:07 CST
5.1.1+
DATE_ISO8601string “Y-m-d\TH:i:sO”
輸出範例:
2010-07-14T20:26:18+0800
5.1.1+
DATE_RFC822string “D, d M y H:i:s O”
輸出範例:
Wed, 14 Jul 10 20:27:39 +0800
5.1.1+
DATE_RFC850string “l, d-M-y H:i:s T”
輸出範例:
Wednesday, 14-Jul-10 20:28:44 CST
5.1.1+
DATE_RFC1036string “D, d M y H:i:s O”
輸出範例:
Wed, 14 Jul 10 20:29:40 +0800
5.1.1+
DATE_RFC1123
DATE_RSS
string “D, d M Y H:i:s T”
輸出範例:
Wed, 14 Jul 2010 20:31:51 CST
5.1.1+
DATE_RFC2822string “D, d M Y H:i:s O”
輸出範例:
Wed, 14 Jul 2010 20:31:51 +0800
5.1.1+
DATE_RFC3339
DATE_ATOM
DATE_W3C
string “Y-m-d\TH:i:sP”
輸出範例:
2010-07-14T20:36:18+08:00
5.1.1+

By Joe Horn • PHP 0 • Tags: constant, PHP

6 月 18 2010

WordPress 3.0 Released

WordPress 3.0 在十幾分鐘前 release 了。

2.9.2 升級可直接把下載下來的壓縮檔直接覆蓋原本的目錄,再透過瀏覽器執行升級程式( wp-admin/upgrade.php )。

因為 WordPress 3.0 的預設佈景主題換了,所以沒改過預設佈景主題的人記得開管理後台檢查一下。

WordPress 3.0 的壓縮檔裡面沒有這些檔案與目錄(注意: wp-content/themes/classic 與 wp-content/themes/default 列在其中),想讓目錄乾淨一點的可以清掉:

  • wp-admin/categories.php
  • wp-admin/edit-category-form.php
  • wp-admin/edit-page-form.php
  • wp-admin/edit-pages.php
  • wp-admin/images/browse-happy.gif
  • wp-admin/images/fav-top.png
  • wp-admin/images/screen-options-left.gif
  • wp-admin/images/wp-logo-vs.gif
  • wp-admin/images/wp-logo.gif
  • wp-admin/import
  • wp-admin/js/wp-gears.dev.js
  • wp-admin/js/wp-gears.js
  • wp-admin/options-misc.php
  • wp-admin/page-new.php
  • wp-admin/page.php
  • wp-admin/rtl.css
  • wp-admin/rtl.dev.css
  • wp-admin/update-links.php
  • wp-admin/wp-admin.css
  • wp-admin/wp-admin.dev.css
  • wp-content/themes/classic
  • wp-content/themes/default
  • wp-includes/js/codepress
  • wp-includes/js/jquery/interface.js
  • wp-includes/js/scriptaculous/prototype.js
  • wp-includes/js/tinymce/wp-tinymce.js

By Joe Horn • WordPress 0 • Tags: Thelonious, WordPress

5 月 27 2010

[PHP] 使用 PDO 要注意的事

以前,我喜歡用 ADOdb 來連接資料庫;自從 PDO 被放進 PHP 5.1 後,它便成了我的新寵…

我在 PHP 5.1.6 環境上幫人家抓蟲時,看到以下兩段程式。

  1. $pdo = New PDO(......);
    
    $sql = "SELECT .....";
    $st = $pdo->prepare($sql);
    $st->execute();
    $rows = $st->fetchAll();
  2. $pdo = New PDO(......);
    
    $sql = "SELECT .....";
    $st = $pdo->query($sql);
    $rows = $st->fetchAll();

雖然以上兩段程式都可以取出 $rows ,但重複並交叉執行的話,就會出現問題。

  • 這段程式可以正確取出 $rows1 與 $rows2:
    $pdo = New PDO(......);
    
    $sql = "SELECT .....";
    $st = $pdo->query($sql);
    $rows1 = $st->fetchAll();
    
    $sql = "SELECT .....";
    $st = $pdo->prepare($sql);
    $st->execute();
    $rows2 = $st->fetchAll();
  • 這段程式只能正確取出 $rows1 ,$rows2 會是個空的陣列:
    $pdo = New PDO(......);
    
    $sql = "SELECT .....";
    $st = $pdo->prepare($sql);
    $st->execute();
    $rows1 = $st->fetchAll();
    
    $sql = "SELECT .....";
    $st = $pdo->query($sql);
    $rows2 = $st->fetchAll();

這問題有兩種解法:

  • 別偷懶,乖乖的用 PDO::prepare 與 PDOStatement->execute。
  • 若要用變數接收 PDO::query 回傳的 PDOStatement,請先 unset(),例: unset($st); 。

By Joe Horn • PHP 1 • Tags: PDO, PDOStatement, PHP

4 月 18 2010

C# 的 ==、Equals 與 JAVA 的 ==、equals

剛感到好奇,各在 C# 與 JAVA 寫測試程式。

  • C#:
    Object myObj1 = 1;
    Object myObj2 = myObj1;
    Object myObj3 = 1;
    
    Console.WriteLine("myObj2.Equals(myObj1) = " + myObj2.Equals(myObj1));
    Console.WriteLine("myObj3.Equals(myObj1) = " + myObj3.Equals(myObj1));
    
    Console.WriteLine("(myObj2 == myObj1) = " + (myObj2 == myObj1));
    Console.WriteLine("(myObj3 == myObj1) = " + (myObj3 == myObj1));

    結果:

    myObj2.Equals(myObj1) = True
    myObj3.Equals(myObj1) = True
    (myObj2 == myObj1) = True
    (myObj3 == myObj1) = False
  • JAVA:
    Object myObj1 = 1;
    Object myObj2 = myObj1;
    Object myObj3 = 1;
    
    System.out.println("myObj2.equals(myObj1) = " + myObj2.equals(myObj1));
    System.out.println("myObj3.equals(myObj1) = " + myObj3.equals(myObj1));
    
    System.out.println("(myObj2 == myObj1) = " + (myObj2 == myObj1));
    System.out.println("(myObj3 == myObj1) = " + (myObj3 == myObj1));

    結果:

    myObj2.equals(myObj1) = true
    myObj3.equals(myObj1) = true
    (myObj2 == myObj1) = true
    (myObj3 == myObj1) = true

By Joe Horn • .NET, JAVA 1 • Tags: C#, JAVA

4 月 16 2010

[Benchmark] eAccelerator v.s. APC on PHP 5.3

FreeBSD ports tree 的 lang/php5 升級到 5.3.2, www/eaccelerator 也升級到 0.9.6。
但是… 目前,FreeBSD ports tree 的 www/pecl-APC 依然是 3.0.19,無法在 PHP 5.3 運作;為了讓它正常運作,jnlin 送過 PR(我沒有先查詢,也送了一個 (羞) )。

其實 eAccelerator 0.9.6 在 2010 年 2 月初就已經釋出了,可是,從 changelog 看來,很多不錯的功能被砍掉(反璞歸真?):

Changes in this version:

* Support for PHP 5.3.
* The encoder is removed
* The user cache functions are removed
* The session handler is removed
* The minimal PHP version supported is now 5.1
* Some internal refactoring to clean up the code
* Fixed some bugs (and probably added some)

這麼看來,2008 年的這篇文章的參考價值就低了些…
為了滿足我自己的好奇心,就把 APC 3.1.3p1 裝起來測試看看。

系統/硬體:

  • CPU: Intel(R) Pentium(R) 4 CPU 3.00GHz
  • Memory: 6G(DDR2 800 MHz, Dual-Channel)
  • FreeBSD 8.0-RELEASE-p2 amd64
  • Apache HTTPD 2.2.14
  • PHP 5.3.2

設定:

  • eAccelerator 0.9.6:
    eaccelerator.shm_size="128"
    eaccelerator.cache_dir="/tmp/eaccelerator"
    eaccelerator.enable="1"
    eaccelerator.optimizer="1"
    eaccelerator.debug="0"
    eaccelerator.log_file="/var/log/eaccelerator.log"
    eaccelerator.name_space = ""
    eaccelerator.check_mtime="1"
    eaccelerator.filter=""
    eaccelerator.shm_max="0"
    eaccelerator.shm_ttl="0"
    eaccelerator.shm_prune_period="0"
    eaccelerator.shm_only="0"
    eaccelerator.compress="1"
    eaccelerator.compress_level="9"
    eaccelerator.keys="shm_and_disk"
  • APC 3.1.3p1:
    apc.enabled=1
    apc.shm_segments=1
    apc.shm_size=128
    apc.ttl=7200
    apc.user_ttl=7200
    apc.num_files_hint=1024
    apc.mmap_file_mask=/tmp/apc.cache
    apc.enable_cli=1

測試結果(ab -c5 -n500):

Pure PHPeAcceleratorAPC
WordPress 2.9.23.00 req./sec.
332.834 ms/req.
7.61 req./sec.
131.487 ms/req.
8.87 req./sec.
112.750 ms/req.
MediaWiki 1.15.31.81 req./sec.
552.822 ms/req.
2.75 req./sec.
363.124 ms/req.
5.93 req./sec.
168.580 ms/req.
Gallery 2.3.13.51 req./sec.
284.979 ms/req.
7.91 req./sec.
126.421 ms/req.
7.38 req./sec.
135.506 ms/req.

依照結果看來,APC 3.1.3p1 的確略勝 eAccelerator 0.9.6。 8-)
可惜的是.. Xcache 目前的最新版本(1.3.0)沒辦法在 PHP 5.3 跑…

By Joe Horn • FreeBSD, PHP, WWW 0 • Tags: Apache, APC, benchmark, eAccelerator, PHP, ports

4 月 1 2010

[MySQL] 處理 weekday 欄位

最近在 MySQL 處理包含 weekday 型態的資料,發覺… 在 MySQL 處理 weekday 真的是「輕鬆寫意」… 8-)

根據 DAYOFWEEK() 與 WEEKDAY() 的定義,回傳的資料都是數值。
而大多數 DBMS 都有取得 weekday 的方法。

我會說「 MySQL 處理 weekday 輕鬆寫意」的原因是… ENUM !
我把將欄位型態定義為 enum(‘Sun’, ‘Mon’, ‘Tue’, ‘Wed’, ‘Thu’, ‘Fri’, ‘Sat’)。
今天(2010/04/01,愚人節)是星期四,若是要抓出該欄位為 Thu 的資料,只要用這種語法:

SELECT ... WHERE `col`= DAYOFWEEK( NOW() )

用這類方法要注意的是,DAYOFWEEK() 與 WEEKDAY() 對於每個 weekday,回傳的數值都不一樣。

By Joe Horn • Database 0 • Tags: DAYOFWEEK, ENUM, MySQL, WEEKDAY

«‹ 6 7 8 9›»

Site Info

All content on this Blog is licensed under CC BY-NC-SA 4.0

About Me

profile for Joe Horn at Stack Overflow, Q&A for professional and enthusiast programmers


My mail!

獅子座

Coffee Powered!

F1 fans

motoGP fans

Linkin Park

I am a Taiwanese!

Recent Comments

  • Avatar of johnpupu johnpupu: PHP 還有這個 phpsavant.c……
  • Avatar of Jerry Jerry: 这个不是foreach的问题。 0 ==……
  • Avatar of Joe Horn Joe Horn: 看來問題在 if ... else ..……
  • Avatar of jnlin jnlin: 因為 'b' 被轉型成 0 了…
  • Avatar of 路人 路人: 跟 foreach 沒有關係 ?…
  • Avatar of bill bill: 註冊表那裡要設定 BasicAuthLe……
  • Avatar of 虫 虫: .svn 的檔案減少可以增加在 wind……
  • Avatar of mars mars: 如果說寫程式是理性極致的話,那寫小說就是……
  • Avatar of Joe Horn Joe Horn: 已更新文章。…
  • Avatar of jackcal jackcal: joehorn.idv.tw關於轉貼 h……

Post Categories

  • About My Sites (16)
  • Computer Hardware (29)
  • Computer Software (45)
  • Database (23)
  • FreeBSD (21)
  • Funny (14)
  • Life (23)
  • Linux (5)
  • Mail (19)
  • Network (12)
  • Programing (40)
    • .NET (5)
    • JAVA (2)
    • Javascript (6)
    • PHP (29)
  • Thoughts (34)
  • Windows (13)
  • WWW (79)
    • phpBB (7)
    • WordPress (18)

Blogroll

  • 這裡沒有美食

Tags Cloud

AMD Apache benchmarking Bloglines Coppermine DNSBL eAccelerator fio Firefox free FreeBSD Gmail Google HDD Hsin-chu HTTPS IE Intel Javascript Lenovo Longhorn Microsoft MySQL Office Percona XtraBackup performance PHP phpBB pirate Postfix restaurant RSS security sendmail software SpamAssassin SSL Subversion Taiwan theme translation VPS Windows WordPress Yahoo

Ads

↑

© Joe Horn 的啟示錄 2025
Powered by WordPress • Themify WordPress Themes