Yii框架模型类的实现以及PHP5动态语言特性的应用
Yii框架提供一个代码生成器gii, 我们一般用它来生成模型类代码。模型类是对数据(表)操作进行封装 不过在模型类中你看不到get/set属性的方法,甚至看不到和表字段关联的属性成员变量,但并不影响我们直接操作其属性,仿佛这些属性就在那里一样。 其具体实现
Yii框架提供一个代码生成器gii, 我们一般用它来生成模型类代码。模型类是对数据(表)操作进行封装
不过在模型类中你看不到get/set属性的方法,甚至看不到和表字段关联的属性成员变量,但并不影响我们直接操作其属性,仿佛这些属性就在那里一样。
其具体实现方式,正是一些设计模式和PHP5动态语言特性的一个很好的应用案例。
举个例子,如下一个用户模型类,对应的数据表为users
<?php class User extends CActiveRecord { /** * The followings are the available columns in table 'users': * @var double $Id * @var string $Username * @var string $Password * @var string $Email */ /** * Returns the static model of the specified AR class. * @return CActiveRecord the static model class */ public static function model($className='User') { return parent::model($className); } /** * @return string the associated database table name */ public function tableName() { return 'users'; } }
现在我们想读取一条user记录,首先当然得构造一个User对象
$user = new User();
可以执行一下var_dump($user),你会发现这个$user有个私有的_md属性(模型的元数据),该属性类型为CActiveRecordMetaData。
在这个_md变量中包含了数据表结构定义(Schema)。
究竟执行了什么代码,会构造出这样一个对象,并且读取了数据表结构定义,下面我们来跟踪一下:
1、和其他面向对象语言一样,在调用new创建一个对象时,首先会调用类的构造函数,如下:
/** * Constructor. * @param string $scenario scenario name. See {@link CModel::scenario} for more details about this parameter. */ public function __construct($scenario='insert') { if($scenario===null) // internally used by populateRecord() and model() return; $this->setScenario($scenario); $this->setIsNewRecord(true); $this->_attributes=$this->getMetaData()->attributeDefaults; $this->init(); ...... }
看起来模型对象元数据的构造以及数据表shema的读取和这个函数有关,继续
/** * Returns the meta-data for this AR * @return CActiveRecordMetaData the meta for this AR class. */ public function getMetaData() { if($this->_md!==null) return $this->_md; else return $this->_md=self::model(get_class($this))->_md; }
/** * Returns the static model of the specified AR class. * The model returned is a static instance of the AR class. */ public static function model($className=__CLASS__) { if(isset(self::$_models[$className])) return self::$_models[$className]; else { $model=self::$_models[$className]=new $className(null); $model->_md=new CActiveRecordMetaData($model); $model->attachBehaviors($model->behaviors()); return $model; } }
注意self::$_models是一个单例模式静态变量,你的应用所加载过的模型都被放在该对象数组中统一管理,你可以把它看作集中的模型对象管理器。看来,即使模型不再被实际使用,已经建立的模型对象也不会被释放。上述代码中创建了一个CActiveRecordMetaData对象,即前述的数据表Schema,注意User模型本身被作为其构造函数的参数被传递了进去,这里类似于应用了一种委托的模式,即模型类把获取数据表Schema的任务委托给CActiveRecordMetaData类。继续看下去,
/** * Constructor. * @param CActiveRecord $model the model instance */ public function __construct($model) { $this->_model=$model; $tableName=$model->tableName(); if(($table=$model->getDbConnection()->getSchema()->getTable($tableName))===null) throw new CDbException(Yii::t('yii','The table "{table}" for active record class "{class}" cannot be found in the database.', array('{class}'=>get_class($model),'{table}'=>$tableName))); ...... }
上述代码中getTable($tableName),这里应该是getTable('User')函数调用了CMysqlSchema的loadTable方法,最终通过SQL语句
SHOW FULL COLUMNS FROM ...
现在我们才刚刚了解到User对象中的元数据和缺省属性成员变量值是怎么来的。
接下来,才是动态语言特性相关部分,我们看看如何通过user对象,来所谓“动态”的操作数据属性的。
数据库中的users表中有Email字段,那么我们现在想给新创建的user对象的Email属性赋值,如下:
$user->Email = 'iefreer@hotmail.com';
如果是传统面向对象语言如c++/java,这里会报编译错误,因为User类没有定义Email成员变量。
而对于PHP5而言,由于语言对动态特性(魔法函数)的支持,这样的调用没有任何问题。我们看看它内部是怎么实现的。
如我之前的PHP语言动态特性文章中所言,设置对象的一个不存在的属性,会触发该对象的__set魔法函数:
/** * PHP setter magic method. * This method is overridden so that AR attributes can be accessed like properties. * @param string $name property name * @param mixed $value property value */ public function __set($name,$value) { if($this->setAttribute($name,$value)===false) { if(isset($this->getMetaData()->relations[$name])) $this->_related[$name]=$value; else parent::__set($name,$value); } }
上述代码中的setAttribute函数会把Email添加到$_attributes这个数组类型的成员变量中,也就是$_attributes充当了模型所对应的数据表属性动态管理器的功能。
再看读取user对象属性的语句:
$email = $user->Email;
类似的,该语句将触发CActiveRecord类的__get魔法函数,会返回$_attributes数组中相应属性的值。
by iefreer

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

在软件技术的前沿,UIUC张令明组携手BigCode组织的研究者,近日公布了StarCoder2-15B-Instruct代码大模型。这一创新成果在代码生成任务取得了显著突破,成功超越CodeLlama-70B-Instruct,登上代码生成性能榜单之巅。StarCoder2-15B-Instruct的独特之处在于其纯自对齐策略,整个训练流程公开透明,且完全自主可控。该模型通过StarCoder2-15B生成了数千个指令,响应对StarCoder-15B基座模型进行微调,无需依赖昂贵的人工标注数

一、前言在过去的几年里,YOLOs由于其在计算成本和检测性能之间的有效平衡,已成为实时目标检测领域的主导范式。研究人员探索了YOLO的架构设计、优化目标、数据扩充策略等,取得了显著进展。同时,依赖非极大值抑制(NMS)进行后处理阻碍了YOLO的端到端部署,并对推理延迟产生不利影响。在YOLOs中,各种组件的设计缺乏全面彻底的检查,导致显著的计算冗余,限制了模型的能力。它提供了次优的效率,以及相对大的性能改进潜力。在这项工作中,目标是从后处理和模型架构两个方面进一步提高YOLO的性能效率边界。为此

評估Java框架商業支援的性價比涉及以下步驟:確定所需的保障等級和服務等級協定(SLA)保證。研究支持團隊的經驗和專業知識。考慮附加服務,如昇級、故障排除和效能最佳化。權衡商業支援成本與風險緩解和提高效率。

目標偵測系統的標竿YOLO系列,再次獲得了重磅升級。自今年2月YOLOv9發布之後,YOLO(YouOnlyLookOnce)系列的接力棒傳到了清華大學研究人員的手上。上週末,YOLOv10推出的消息引發了AI界的關注。它被認為是電腦視覺領域的突破性框架,以其即時的端到端目標檢測能力而聞名,透過提供結合效率和準確性的強大解決方案,延續了YOLO系列的傳統。論文網址:https://arxiv.org/pdf/2405.14458專案網址:https://github.com/THU-MIG/yo

今年2月,Google上線了多模態大模型Gemini1.5,透過工程和基礎設施最佳化、MoE架構等策略大幅提升了效能和速度。擁有更長的上下文,更強推理能力,可以更好地處理跨模態內容。本週五,GoogleDeepMind正式發布了Gemini1.5的技術報告,內容涵蓋Flash版等最近升級,該文件長達153頁。技術報告連結:https://storage.googleapis.com/deepmind-media/gemini/gemini_v1_5_report.pdf在本報告中,Google介紹了Gemini1

PHP框架的學習曲線取決於語言熟練度、框架複雜性、文件品質和社群支援。與Python框架相比,PHP框架的學習曲線較高,而與Ruby框架相比,則較低。與Java框架相比,PHP框架的學習曲線中等,但入門時間較短。

出品|51CTO技術棧(微訊號:blog51cto)Mistral發布了首個程式碼模型Codestral-22B!該模型的瘋狂之處不僅在於訓練了80多種程式語言,包括許多程式碼模型忽略的Swift等。他們的速度沒有完全一致。要求使用Go語言編寫一個「發布/訂閱」系統。這裡的GPT-4o正在輸出,Codestral已經快到看不清楚的速度交捲了!由於該模型剛剛推出,尚未公開測試。但根據Mistral的負責人說法,Codestral是目前表現最佳的開源程式碼模型。圖片有興趣的朋友可以移步:-抱抱臉:https

一般而言,訓練神經網路耗費的運算量越大,其效能就越好。在擴大計算規模時,必須要做個決定:是增加模型參數量還是提升資料集大小-必須在固定的計算預算下權衡這兩個因素。增加模型參數量的好處是可以提高模型的複雜度和表達能力,從而更好地擬合訓練資料。然而,過多的參數可能導致過度擬合,使得模型在未見過的數據上表現不佳。另一方面,擴大資料集大小可以提高模型的泛化能力,減少過度擬合問題。我們告訴你們:只要能適當分配參數和數據,就能在固定計算預算下達到效能最大化。之前已有不少研究探索過神經語言模型的Scalingl
