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脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

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

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

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

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

目标检测系统的标杆YOLO系列,再次获得了重磅升级。自今年2月YOLOv9发布之后,YOLO(YouOnlyLookOnce)系列的接力棒传到了清华大学研究人员的手上。上周末,YOLOv10推出的消息引发了AI界的关注。它被认为是计算机视觉领域的突破性框架,以实时的端到端目标检测能力而闻名,通过提供结合效率和准确性的强大解决方案,延续了YOLO系列的传统。论文地址:https://arxiv.org/pdf/2405.14458项目地址:https://github.com/THU-MIG/yo

评估Java框架商业支持的性价比涉及以下步骤:确定所需的保障级别和服务水平协议(SLA)保证。研究支持团队的经验和专业知识。考虑附加服务,如升级、故障排除和性能优化。权衡商业支持成本与风险缓解和提高效率。

今年2月,谷歌上线了多模态大模型Gemini1.5,通过工程和基础设施优化、MoE架构等策略大幅提升了性能和速度。拥有更长的上下文,更强推理能力,可以更好地处理跨模态内容。本周五,GoogleDeepMind正式发布了Gemini1.5的技术报告,内容覆盖Flash版等最近升级,该文档长达153页。技术报告链接:https://storage.googleapis.com/deepmind-media/gemini/gemini_v1_5_report.pdf在本报告中,谷歌介绍了Gemini1

写在前面&笔者的个人理解最近来,随着深度学习技术的发展和突破,大规模的基础模型(FoundationModels)在自然语言处理和计算机视觉领域取得了显着性的成果。基础模型在自动驾驶当中的应用也有很大的发展前景,可以提高对于场景的理解和推理。通过对丰富的语言和视觉数据进行预训练,基础模型可以理解和解释自动驾驶场景中的各类元素并进行推理,为驾驶决策和规划提供语言和动作命令。基础模型可以根据对驾驶场景的理解来实现数据增强,用于提供在常规驾驶和数据收集期间不太可能遇到的长尾分布中那些罕见的可行

轻量级PHP框架通过小体积和低资源消耗提升应用程序性能。其特点包括:体积小,启动快,内存占用低提升响应速度和吞吐量,降低资源消耗实战案例:SlimFramework创建RESTAPI,仅500KB,高响应性、高吞吐量

一般而言,训练神经网络耗费的计算量越大,其性能就越好。在扩大计算规模时,必须要做个决定:是增多模型参数量还是提升数据集大小——必须在固定的计算预算下权衡这两项因素。增加模型参数量的好处是可以提高模型的复杂度和表达能力,从而更好地拟合训练数据。然而,过多的参数可能导致过拟合,使得模型在未见过的数据上表现不佳。另一方面,扩大数据集大小可以提高模型的泛化能力,减少过拟合问题。我们告诉你们:只要能适当分配参数和数据,就能在固定计算预算下实现性能最大化。之前已有不少研究探索过神经语言模型的Scalingl
