peacq / picorm
Requires
- php: >=5.4.0
This package is not auto-updated.
Last update: 2024-09-15 01:50:48 UTC
README
一个轻量级的PHP ORM。
PicORM可以帮助你将MySQL数据库行映射到PHP对象,并在它们之间创建关系。
PicORM是一个易于安装和使用的Active Record模式实现。
你需要知道的一些事情
- 目前还不能有多个主键
- 目前还不能使用与关系表中数据的多对多关系
- 鼓励Fork和提交pull request!
安装
通过composer
使用curl -sS https://getcomposer.org/installer | php
在www文件夹中安装composer
创建一个composer.json
文件
{ "require": { "picorm/picorm": "0.0.6" } }
使用php composer.phar install
安装PicORM
从源码
克隆https://github.com/iNem0o/PicORM
仓库,并使用以下方式包含PicORM
自动加载:
require('path/to/PicORM/src/autoload.inc.php');
加载和配置PicORM
在开始使用PicORM
之前,你必须进行配置。datasource
是唯一必需的参数,必须是一个PDO实例
\PicORM\PicORM::configure(array( 'datasource' => new PDO('mysql:dbname=DBNAME;host=HOST', 'DBLOGIN', 'DBPASSWD') ));
模型
实现一个模型
首先,你必须创建一个表,该模型将被映射到该表
CREATE TABLE `brands` ( `idBrand` int(11) NOT NULL AUTO_INCREMENT, `nameBrand` varchar(100) NOT NULL, `noteBrand` float DEFAULT 0, PRIMARY KEY (`idBrand`) ) ENGINE=MyISAM;
然后创建一个继承自\PicORM\Model
的类。你必须实现一些静态参数来描述你的MySQL表模式,如果你忘记了其中任何一个,\PicORM\Exception
将会提醒你
必需的
protected static $_tableName
MySQL表名
protected static $_primaryKey
表主键字段名
protected static $_tableFields
不包括主键的所有mysql表字段名的数组
可选的
protected static $_databaseName
如果与数据源主DB不同,则为数据库的名称
然后,为表字段添加一个公共属性,使用public $fieldName
品牌模型声明
class Brand extends \PicORM\Model { protected static $_tableName = 'brands'; protected static $_primaryKey = 'idBrand'; protected static $_tableFields = array( 'nameBrand', 'noteBrand' ); public $idBrand; public $nameBrand; public $noteBrand; }
创建和保存
// creating new model $brand = new Brand(); // setting field $brand -> nameBrand = 'Peugeot'; // save model $brand -> save();
更新和删除
// Criteria with exact value (idBrand=10) $brand = Brand :: findOne(array('idBrand' => 10)); // setting model property $brand -> nameBrand = 'Audi'; // save model $brand -> save(); // save model $brand -> delete();
find() 和 findOne()
Model
的每个子类都继承自静态方法 find()
和 findOne()
。
这些方法用于从数据库行中填充模型。
/** * Find one model from criteria, allowing to order * @param array $where - associative * @param array $order - associative array */ public static function findOne($where = array(), $order = array()) /** * Return Collection instance from criteria, allowing to order and limit result * @param array $where - associative array * @param array $order - associative array * @param int $limitStart - int * @param int $limitEnd - int * @return Collection */ public static function find($where = array(),$order = array(), $limitStart = null, $limitEnd = null)
如何使用 $where 参数
此参数是构建WHERE mysql子句的数据
// simple criteria $where = array('field' => 1); // custom operator $where = array('field' => array('operator' => '<=', 'value' => '20') ); // raw sql value (NOT prepared, beware of SQL injection) $where = array( 'field' => array('IN (5,6,4)'), 'dateTime' => array('NOW()') );
如何使用 $order 参数
此参数是构建ORDER mysql子句的数据
$order = array( 'field'=>'ASC', 'field2' => DESC, 'RAND() => '' )
集合
PicORM中的集合通过::find()
方法创建,在\PicORM\Model
的每个子类上静态访问。
一旦你有一个新的\PicORM\Collection实例,数据尚未检索。检索仅在尝试使用以下方式之一访问数据时才进行:
集合的使用
// php array access $firstResult = $collection[0]; // counting collection $nbResults = count($collection); // using getter $firstResult = $collection->get(0); // iterate over the collection foreach($collection as $model) // or manual fetching / re-fetching $collection->fetch();
\PicORM\Collection实例可以在检索数据之前对集合成员执行UPDATE和DELETE查询,这样使用update()
或delete()
方法将仅根据find()
限制参数生成一个基于MySQL查询的查询。
// Delete all models in collection $collection = Brand::find(array('noteBrand' => 10)) -> delete(); // Update and set noteBrand = 5 to collection $collection = Brand::find(array('noteBrand' => array('IN(9,10,11)'))) -> update(array('noteBrand' => 5));
集合分页
集合的分页基于MySQL的FOUND_ROWS()。记住,集合在您使用之前不会检索数据。当您有一个集合实例时,您可以通过以下方式轻松激活分页:
$carCollection = Car::find(); // grab all car from database $carCollection->activePagination(50); // asking for 50 models by page $carCollection->paginate(1); // asking for first page
现在您可以访问另外两个方法。
$nbTotalPages = $carCollection -> getTotalPages(); $nbTotalModels = $carCollection -> foundModels();
集合高级查询
您可以在执行之前使用集合上的getQueryHelper()
方法更改检索查询。您将获得一个InternalQueryHelper
的实例,您可以对其进行操作。完成后,只需使用setQueryHelper($helper)
设置集合查询助手即可。
这样,您可以在模型实例中加载自定义数据。
$cars = Car::find(); $queryBuilder = $cars->getQueryHelper(); $queryBuilder->select("COUNT(idTag) as nbTags"); $queryBuilder->leftJoin('car_has_tag cht', 'cht.idCar = cars.idCar'); $queryBuilder->groupBy("cars.idCar"); $cars->setQueryHelper($queryBuilder);
模型之间的关系
使用关系需要在您的模型子类中添加一个属性和一个方法。
protected static $_relations = array();
需要实现以存储模型关系,需要实现 protected static function defineRelations() { }
方法来声明你的关系
在子类中重写 defineRelations()
允许你使用以下 3 种方法之一声明你特定的模型关系。
/** * Add a OneToOne relation * @param $sourceField - model source field * @param $classRelation - relation model classname * @param $targetField - related model target field * @param array $autoGetFields - field to auto get from relation when loading model * @param string $aliasRelation - override relation auto naming className with an alias * (ex : for reflexive relation) */ protected static function addRelationOneToOne($sourceField, $classRelation, $targetField, $autoGetFields = array(), $aliasRelation = '') /** * Add a OneToMany relation * @param $sourceField - model source field * @param $classRelation - relation model classname * @param $targetField - related model target field * @param string $aliasRelation - override relation auto naming className with an alias */ protected static function addRelationOneToMany($sourceField, $classRelation, $targetField, $aliasRelation = '') /** * Add a ManyToMany relation * @param $sourceField - model source field * @param $classRelation - relation model name * @param $targetField - related model field * @param $relationTable - mysql table containing the two models ID * @param string $aliasRelation - override relation auto naming className */ protected static function addRelationManyToMany($sourceField, $classRelation, $targetField, $relationTable, $aliasRelation = '')
使用关系
此示例将使用以下 MySQL 模式
CREATE TABLE `brands` ( `idBrand` int(11) NOT NULL AUTO_INCREMENT, `nameBrand` varchar(100) NOT NULL, `noteBrand` float DEFAULT 0, PRIMARY KEY (`idBrand`) ) ENGINE=MyISAM; CREATE TABLE `cars` ( `idCar` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, `idBrand` INT NOT NULL, `nameCar` VARCHAR(100) NOT NULL ) ENGINE = MYISAM ; CREATE TABLE `car_have_tag` ( `idCar` INT NOT NULL, `idTag` INT NOT NULL, PRIMARY KEY (`idCar`,`idTag`) ) ENGINE = MYISAM ; CREATE TABLE `tags` ( `idTag` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, `libTag` VARCHAR(255) NOT NULL ) ENGINE = MYISAM ;
首先,你需要声明你的 3 个模型及其关系
class Brand extends Model { protected static $_tableName = 'brands'; protected static $_primaryKey = "idBrand"; protected static $_relations = array(); protected static $_tableFields = array( 'nameBrand', 'noteBrand' ); public $idBrand; public $nameBrand; public $noteBrand; protected static function defineRelations() { // create a relation between Brand and Car // based on this.idBrand = Car.idBrand self::addRelationOneToMany('idBrand', 'Car', 'idBrand'); } } class Car extends Model { protected static $_tableName = 'cars'; protected static $_primaryKey = "idCar"; protected static $_relations = array(); protected static $_tableFields = array( 'idBrand', 'nameCar' ); public $idCar; public $idBrand; public $nameCar = ''; protected static function defineRelations() { // create a relation between Car and Brand // based on this.idBrand = Brand.idBrand // nameBrand is added to autoget fields which is automatically fetched // when model is loaded self::addRelationOneToOne('idBrand', 'Brand', 'idBrand', 'nameBrand'); // create a relation between Car and Tag using a relation table car_have_tag self::addRelationManyToMany("idCar","Tag","idTag","car_have_tag"); } } class Tag extends Model { protected static $_tableName = 'tags'; protected static $_primaryKey = "idTag"; protected static $_relations = array(); protected static $_tableFields = array( 'libTag', ); public $idTag; public $libTag = ''; protected static function defineRelations() { // create a relation between Tag and Car using a relation table car_have_tag self::addRelationManyToMany('idTag','Car','idCar','car_have_tag'); } }
现在你可以开始创建和操作相关模型
// creating a brand $brand = new Brand(); $brand -> nameBrand = "Peugeot"; $brand -> save(); // creating a car $car = new Car(); $car -> nameCar = "205 GTi"; // setting car's brand $car -> setBrand($brand); // other way to setting car's brand $car -> idBrand = $brand -> idBrand; $car -> save(); // if we look for our car $car = Car :: findOne(array('nameCar' => '205 GTi')); // we can get brand of the car $car -> getBrand(); // or we can access brand name directly because it has been added to relation auto get fields $car -> nameBrand;
由于你声明了从品牌到汽车的单一到多对关系,因此你也可以在另一端使用设置器和获取器
// get all cars from brand // method return instance of \PicORM\Collection foreach($brand -> getCar() as $cars) // get all cars from brand with custom criteria // parameters are same as find() method // method return instance of \PicORM\Collection $brand -> getCar($where,$order,$limitStart,$limitStop);
多对多关系也很容易使用
// creating some tags $tag = new Tag(); $tag -> libTag = 'tag 1'; $tag -> save(); $tag2 = new Tag(); $tag2 -> libTag = 'tag 2'; $tag2 -> save(); $tag3 = new Tag(); $tag3 -> libTag = 'tag 3'; $tag3 -> save(); // setting car's tags $car -> setTag(array($tag,$tag2,$tag3)); // getting car's tags (return instance of \PicORM\Collection) $car -> getTag(); // getting car's tags with custom criteria // parameters are same as find() method // method return instance of \PicORM\Collection $car -> getTag($where,$order,$limitStart,$limitStop); // unset relation between $car and $tag2 $car -> unsetTag($tag2);
变更日志
不稳定 0.0.1
- 初始版本
不稳定 0.0.2
- 错误修复
- 添加命名空间支持和 pdo 检索模式选择
- 添加事务支持
BETA 0.0.3
- 错误修复
- 重构 MySQL
- 集合
- 测试
BETA 0.0.4
- 重构实体到模型
- QueryBuilder:SQL 提示和 FoundRows
- 集合分页
- 测试
BETA 0.0.5
- 自定义集合查询构建器
- 从 SQL_CALC_FOUND_ROWS 移动到 count(*)
- 修复关系别名名称大小写错误
- 修复关系获取器中存在 LIMIT 子句的错误
- 修复多对多获取器中没有 WHERE / ORDER / LIMIT 的错误
- 重构代码
- 重构 PHPDoc
- 重构测试
- 添加 TravisCI
BETA 0.0.6
- 添加数据库和表的设置器
- 错误修复:更新查询未使用 tablename 获取器
- 错误修复:在多对多获取器中,WHERE 值未以表名前缀
- 更新 README