iT邦幫忙

0

php 命名空間用自動加載類別,並用PDO::FETCH_CLASS 轉換成類別

/*
請問 php 用自動加載類別的方式
並將數據庫的資料用 PDO::FETCH_CLASS 轉換成 xxx 類別

xxx 類別是放在 classes/xxx.php 內
class xxx{
	public $name;
}

在別的網頁執行以下程式碼是沒問題的
*/

function class_loader($class){
	require("classes/{$class}.php");
}
spl_autoload_register('class_loader');

$q = "SELECT `name` FROM `xxx`";
$pdo = new PDO( 連線資訊 );
$stmt = $pdo->prepare($q);
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_CLASS, 'xxx');
while($n = $stmt->fetch()){	
	echo $n->name.'<br />';
}

/*
但是如果我在 classes/xxx.php 內加上命名空間
namespace my;
class xxx{
	public $name;
}
這樣就會錯誤,請問要如何修正呢?
謝謝大家
*/
看更多先前的討論...收起先前的討論...
weiclin iT邦高手 4 級 ‧ 2016-07-23 11:48:47 檢舉
建議可以在發生錯誤的地方附上錯誤訊息, 不要只是說發生錯誤..
samjam iT邦新手 4 級 ‧ 2016-07-23 12:31:47 檢舉
好的,我了解了,謝謝weiclin的提醒
weiclin iT邦高手 4 級 ‧ 2016-07-23 13:18:15 檢舉
另外關於 autoload 與 namespace, 你還可以參考 psr4 與 composer, 這些現成的就很好用嘍
samjam iT邦新手 4 級 ‧ 2016-07-24 15:14:22 檢舉
好,謝囉

1 個回答

2
fillano
iT邦超人 1 級 ‧ 2016-07-23 01:14:41
最佳解答

namespace是為了防止class name衝突而設計的機制,最簡單的實現方式就是在儲存體上分離,也就是用namespace當做路徑,class name當做檔名。

例如auto loader可以改成這樣(這個寫法要php-5.3之後才支援,因為使用了匿名函數):

spl_autoload_register(function($name) {
    if(class_exists($name) || interface_exists($name)) {
        return;
    }
    $name = str_replace("\\", '/', $name);
    if(file_exists('classes/' . $name . '.php')) {
        require 'classes/' . $name . '.php';
    }
    return;
});

在你的例子中,加上namespace my;之後,配合這個auto loader,就要把class xxx的檔案移到classes/my/xxx.php。

另外,在叫用時,也需要加上namespace,所以setFetchMode的參數應該改成'my\xxx'才對。

說實話,手冊上官方的例子在實作namespace的部份有點弱XD,可以參考一下後面一些使用者分享的例子。

samjam iT邦新手 4 級 ‧ 2016-07-23 12:33:06 檢舉

用您的方式解決問題了,謝謝fillano

我要發表回答

立即登入回答