我在PHP中有一些expierence,但在应用程序架构中没有人 现在我想要打造自己的“自行车”。这是没用的东西,可能是迷你框架或迷你应用程序,我想在这里得到一些exp。
我现在需要编写与数据库一起工作的类和实体的classese(其中一个是User
)
我有以下数据库代码(省略了一些cheks和方法来缩小这个问题):
namespace DataBase;
class DataBase {
/**
*
* @var \PDO $pdo
*/
public $pdo;
public function __construct($host, $dbname, $username, $password=''){
$this->pdo = new \PDO('mysql:host='.$host.';dbname='.$dbname, $username, $password,
array(\PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'"));
$this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
}
/**
*
* @param string $statement
* @return Statement
*/
public function prepare($statement){
return new Statement($this->pdo->prepare($statement));
}
}
namespace DataBase;
class Statement {
private $stmt;
public function __construct(\PDOStatement $stmt) {
$this->stmt = $stmt;
}
public function query() {
try {
$this->stmt->execute();
return $this; //for chaining
}
public function bind($key, $value) {
$this->stmt->bindValue($key, $value, $this->typeof($value));
return $this; //for chaining
}
//some methods for fetching data(works with fetch,fetchAll, fetchColumn and different PDO::FETCH_ methods
public function fetchUpdate($obj) {
$this->stmt->setFetchMode(\PDO::FETCH_INTO, $obj);
$this->stmt->fetch();
}
public function fetchRow() {
return $this->stmt->fetch(\PDO::FETCH_OBJ);
}
public function fetchRowClass($class) {
return $this->stmt->fetchObject($class);
}
}
和User类的一些虚拟
<?php
/**
* Description of User
*
* @author riad
*/
class User {
private $id;
private $name = null;
private $status = null;
private $hasInfo = false;
private static $cache=array();
public function __construct() {
}
public function getId() {
return $this->id;
}
public function getName() {
if(!$this->hasInfo)
$this->getInfo ();
return $this->name;
}
public function isAuthorized(){
return $this->status!="noauth";
}
public static function createById($id) {
// I want this method to cerate user from id, then get info only I will use it after that
if(array_key_exists($id,self::$cache)){
return self::$cache[$id];
}
$user = new User;
$user->id = $id;
return $user;
}
private function getInfo(){
try{
\FrontController::getInstance()->getDB()->
prepare('SELECT * FROM `users` WHERE `id`=:id')->
bind('id', $this->id)->query()->fetchUpdate($this);
$this->hasInfo = true;
}
catch(\DataBase\NotFoundException $dbe){
$this->status = "deleted";
}
}
public static function createFromRequest($request){
$user = new User;
try{
//try get data from cookie
\FrontController::getInstance()->getDB()->
prepare('SELECT * FROM `users` WHERE `session` = :session AND `id`= :id')->
bind('id', $id)->bind('session',$session)->query()->
fetchUpdate($user);
}
catch(... $e){
$user->status = "noauth";
$user->id = 0;
// make it unregged
}
return $user;
}
}
?>
我遇到了一些问题。
public function __call($name,$value){
//do nothing;
}
$stmt->fetchUpdate($obj)
我知道我可以使用public function __call($name,$value){
$this->$name=$value;
}
,但它是宣告道具公众而且它在路上有第一点
我也可以使用public function __call($name,$value){
if($name=='id'){
$this->id=$value;
}
else if($name=='status'){
$this->status=$value;
}
}
但是为每个实体类编写它并不舒服,而不是从这种方法的宣传中保存$this->hasInfo
设置为true
。我知道我可以将我的Database
类更改为始终将某个变量设置为true
,默认情况下它是假的。但它似乎并不优雅。id
时更新缓存(可能用作主流点)fetchRowClass
直接写道具并像使用fetchUpdate一样使用setter?或者可以允许fetchUpdate
直接访问?我知道我自己写了很多代码,但我想要你的意见:
希望,阅读和理解并不是那么难 很高兴看到任何建议 关于亚历克斯
答案 0 :(得分:1)
很少提示:[基于我自己使用的经验和框架]
基本上你应该/想要/可能做的是为你模型中的所有clases创建一个SuperClass。此类将包含对数据库实例的引用,它将包含模型的所有常用方法,即getById($id)
,getAll()
,getPaginated()
等。
此SuperClass的另一个目标是将数据库中的结果映射到模型类的实例中。因此,最后,您的用户类将只具有特定于该类的属性,访问器和方法,例如特殊查询或类似的东西。
以下是一个示例:
Class Model{
protected function getById($_id){
$_table = get_class($this);
$anonymous = $this->_getObjectById($_table,$_id); //this method will execute a query (unsing PDO) and return a StdClass object with the results
$this->mapTable($anonymous,$_table); //this method will take the StdClass instance and will transform it into a $_table Instance
}
private function mapTable($stdInstance,$model_name){
foreach($stdInstance as $key => $value){
try{
if(property_exists($this,$key)){
$this->$key = $value; //you could declare the model's properties as protected... or you could create accessors and call them here
}
} catch(Exception $ex) {
/* something went wrong o_O */
}
}
Class User extends Model{
protected $id;
protected $name;
.....
}
Class Controller{
public function index(){
$user = new User();
$user->getById($_GET['id']);
print_r($user);
//now you can pass the $user object to the View to display it
}
}
用几句话来说...... Model类是一个非常小的ORM。您可以尝试创建自己的ORM,(就像我一样)但是在尝试映射对象之间的关系时会遇到很多问题:Nx1,1xN,NxN,1x1,继承,“更深层次的关系”和{{ 3}}。您还需要以某种方式定义模型结构,以便ORM可以理解它,可能使用YAML / XML文件或直接从数据库的表结构中读取结构,或者在属性中使用命名约定......
这是一个非常有趣的领域:)
希望这会有所帮助,祝你好运