学习yaf 总结笔记
记录下来,方便查看
项目任何地方都可以使用这句代码获取配置 \Yaf\Application::app()->getConfig(); 额外的配置 随着项目越来越庞大,配置也会越来越复杂,如果都放在项目默认的配置文件application.ini中,可能配置会有好几百行,这样就不容易维护了。一般我们会考虑新建配置文件用来存储额外的配置。yaf中提供了\Yaf\Config\Ini类来处理这些额外的配置文件。 1 $config = new \Yaf\Config\Ini(APPLICATION_PATH . '/conf/url.ini', ini_get('yaf.environ')); 在实际读取的时候,最好能设置一个静态变量保存读取到的配置,避免重复申请系统open函数调用。如下: static $config = null; if ($config === null) { $config = new \Yaf\Config\Ini(APPLICATION_PATH . '/conf/url.ini', ini_get('yaf.environ')); } yaf配置文档:http://www.laruence.com/manual/yaf.ini.html yaf.environ product PHP_INI_ALL 环境名称, 当用INI作为Yaf的配置文件时, 这个指明了Yaf将要在INI配置中读取的节的名字 yaf.library NULL PHP_INI_ALL 全局类库的目录路径 yaf.cache_config 0 PHP_INI_SYSTEM 是否缓存配置文件(只针对INI配置文件生效), 打开此选项可在复杂配置的情况下提高性能 yaf.name_suffix 1 PHP_INI_ALL 在处理Controller, Action, Plugin, Model的时候, 类名中关键信息是否是后缀式, 比如UserModel, 而在前缀模式下则是ModelUser yaf.name_separator "" PHP_INI_ALL 在处理Controller, Action, Plugin, Model的时候, 前缀和名字之间的分隔符, 默认为空, 也就是UserPlugin, 加入设置为"_", 则判断的依据就会变成:"User_Plugin", 这个主要是为了兼容ST已有的命名规范 yaf.forward_limit 5 PHP_INI_ALL forward最大嵌套深度 yaf.use_namespace 0 PHP_INI_SYSTEM 开启的情况下, Yaf将会使用命名空间方式注册自己的类, 比如Yaf_Application将会变成Yaf\Application yaf.use_spl_autoload 0 PHP_INI_ALL 开启的情况下, Yaf在加载不成功的情况下, 会继续让PHP的自动加载函数加载, 从性能考虑, 除非特殊情况, 否则保持这个选项关闭 项目配置文件 http://www.laruence.com/manual/yaf.config.optional.html application.dispatcher.defaultModule String index application.dispatcher.defaultController String index 默认的控制器 application.dispatcher.defaultAction String index 默认的动作 application.view.ext String phtml 视图模板扩展名 application.modules String Index 声明存在的模块名, 请注意, 如果你要定义这个值, 一定要定义Index Module application.system.* String * 通过这个属性, 可以修改yaf的runtime configure, 比如application.system.lowcase_path, 但是请注意只有PHP_INI_ALL的配置项才可以在这里被修改, 此选项从2.2.0开始引入 第 5 章 自动加载器 http://www.laruence.com/manual/yaf.autoloader.html 而对于非框架MVC相关的类, Yaf支持全局类和自身类的两种加载方式, 并且Yaf支持大小写敏感和不敏感两种方式来处理文件路径 7.2. Yaf支持的Hook Yaf定义了6个Hook, 它们分别是: 触发顺序 名称 触发时机 说明 1 routerStartup 在路由之前触发 这个是7个事件中, 最早的一个. 但是一些全局自定的工作, 还是应该放在Bootstrap中去完成 2 routerShutdown 路由结束之后触发 此时路由一定正确完成, 否则这个事件不会触发 3 dispatchLoopStartup 分发循环开始之前被触发 4 preDispatch 分发之前触发 如果在一个请求处理过程中, 发生了forward, 则这个事件会被触发多次 5 postDispatch 分发结束之后触发 此时动作已经执行结束, 视图也已经渲染完成. 和preDispatch类似, 此事件也可能触发多次 6 dispatchLoopShutdown 分发循环结束之后触发 此时表示所有的业务逻辑都已经运行完成, 但是响应还没有发送 而插件方法, 可以接受俩个参数, Yaf_Request_Abstract实例和Yaf_Response_Abstract实例. 一个插件类例子如下: 例 7.1.插件类: class UserPlugin extends Yaf_Plugin_Abstract { public function routerStartup(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) { } public function routerShutdown(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) { } } 这个例子中, 插件UserPlugin只关心俩个事件. 所以就定义了俩个方法. 插件要生效, 还需要向Yaf_Dispatcher注册, 那么一般的插件的注册都会放在Bootstra中进行. 一个注册插件的例子如下: 例 7.2. 注册插件 class Bootstrap extends Yaf_Bootstrap_Abstract{ public function _initPlugin(Yaf_Dispatcher $dispatcher) { $user = new UserPlugin(); $dispatcher->registerPlugin($user); } } af\Dispatcher::getInstance()->flushInstantly($flag); 注意:_auto_render设置为0时,_return_response和_instantly_flush的设置将无效。 Yaf\Controller_Abstract类的属性 yafAutoRender 作用:自动渲染功能开头,默认null。此属性的作用与Yaf\Dispather类的_auto_render作用相同,但是优先级更高。 PHP代码设置: 1 $this->yafAutoRender = true; 其中$this代表实现Yaf\Controller_Abstract的控制器类的当前实例。 Yaf响应输出响应相关的方法 1 Yaf\Controller_Abstract::display($template_file); 作用:渲染模板并输出结果 1 Yaf\Controller_Abstract::render($template_file); 作用:渲染模板,并返回结果 1 Yaf\Response_Abstract::setBody($content, $type); 作用:设置响应正文内容为$content,类型为$type;也即设置Yaf\Response_Abstract的_body属性键为$type对应的值为$content。注意如果已经存在则为追加模式。 1 Yaf\Response_Abstract::getBody($type = 'content'); 作用:获取$type对应的响应正文 1 Yaf\Response_Abstract::response(); 作用:输出所有类型的响应正文 1 Yaf\Response_Abstract::clearBody($type); /* Set Content-Type */ $response = $this -> getResponse(); $response -> setHeader( 'Content-Type', 'text/html; charset=utf-8' ); $response -> response(); /* Set HTTP Status */ $response = $this -> getResponse(); $response -> setHeader( $this -> getRequest() -> getServer( 'SERVER_PROTOCOL' ), '404 Not Found' ); $response -> response(); Yaf_Dispatcher::getApplication — 获取当前的Yaf_Application实例 Yaf_Dispatcher::getInstance — 获取当前的Yaf_Dispatcher实例 Yaf_Dispatcher::getRequest — 获取当前的请求实例 Yaf_Dispatcher::getRouter — 获取路由器 Yaf_Dispatcher::initView — 初始化视图引擎并返回它 Yaf_Dispatcher::registerPlugin — 注册一个插件 Yaf_Dispatcher::returnResponse — The returnResponse purpose Yaf_Dispatcher::setDefaultAction — 设置路由的默认动作 Yaf_Dispatcher::setDefaultController — 设置路由的默认控制器 Yaf_Dispatcher::setDefaultModule — 设置路由的默认模块 Yaf_Dispatcher::setErrorHandler — 设置错误处理函数 Yaf_Dispatcher::setRequest — The setRequest purpose Yaf_Dispatcher::setView — 设置视图引擎 web服务器配置: apache #.htaccess, 当然也可以写在httpd.conf RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule .* index.php nginx server { listen ****; server_name domain.com; root document_root; index index.php index.html index.htm; if (!-e $request_filename) { rewrite ^/(.*) /index.php/$1 last; } } $this->getRequest()-> getModuleName() 获取当前请求被路由到的模块名称,首字母大写形式 getControllerName() 获取当前请求被路由到的控制器名称,首字母大写形式 getActionName() 获取当前请求被路由到的动作名称 getRequestUri() 获取当前请求的request_uri getMethod() 获取请求方法, GET、POST、HEAD等 getServer(string $name [, string $default]) 获取$_SERVER变量的值 getParam(string $name [, string $default]) 获取路由参数$name的值(路由协议根据request_uri解析出来的参数,与$_GET、$_POST不等同) getParams() 获取所有路由参数 isCli() 是否从命令行运行 isGet() HTTP请求方法是否为GET方法 isPost() 是否为POST方法 isHead() 是否为HEAD方法(该方法只返回HTTP报头)和状态行 sXmlHttpRequest() 是否为Ajax请求($_SERVER['HTTP_X_REQUESTED_WITH']的值为’XMLHttpRequest’) getPost(string $name [, string $default]) 获取$_POST变量的值 getQuery(string $name [, string $default]) 获取$_GET变量的值 getFiles() 返回$_FILES get(string $name [, string $default]) 从请求参数中寻找参数name,如果没有找到的话,将从POST, GET, Cookie, Server中寻找 getCookie(string $name [, string $default]) 获取Cookie的值 Subquery in joins: $usersQ = $db->subQuery ("u"); $usersQ->where ("active", 1); $usersQ->get ("users"); $db->join($usersQ, "p.userId=u.id", "LEFT"); $products = $db->get ("products p", null, "u.login, p.productName"); print_r ($products); // SELECT u.login, p.productName FROM products p LEFT JOIN (SELECT * FROM t_users WHERE active = 1) u on p.userId=u.id; EXISTS / NOT EXISTS condition $sub = $db->subQuery(); $sub->where("company", 'testCompany'); $sub->get ("users", null, 'userId'); $db->where (null, $sub, 'exists'); $products = $db->get ("products"); // Gives SELECT * FROM products WHERE EXISTS (select userId from users where company='testCompany') Has method A convenient function that returns TRUE if exists at least an element that satisfy the where condition specified calling the "where" method before this one. $db->where("user", $user); $db->where("password", md5($password)); if($db->has("users")) { return "You are logged"; } else { return "Wrong user/password"; } Helper methods Join Conditions Add AND condition to join statement $db->join("users u", "p.tenantID=u.tenantID", "LEFT"); $db->joinWhere("users u", "u.tenantID", 5); $products = $db->get ("products p", null, "u.name, p.productName"); print_r ($products); // Gives: SELECT u.login, p.productName FROM products p LEFT JOIN users u ON (p.tenantID=u.tenantID AND u.tenantID = 5) Add OR condition to join statement $db->join("users u", "p.tenantID=u.tenantID", "LEFT"); $db->joinOrWhere("users u", "u.tenantID", 5); $products = $db->get ("products p", null, "u.name, p.productName"); print_r ($products); // Gives: SELECT u.login, p.productName FROM products p LEFT JOIN users u ON (p.tenantID=u.tenantID OR u.tenantID = 5) Ordering method $db->orderBy("id","asc"); $db->orderBy("login","Desc"); $db->orderBy("RAND ()"); $results = $db->get('users'); // Gives: SELECT * FROM users ORDER BY id ASC,login DESC, RAND (); Order by values example: $db->orderBy('userGroup', 'ASC', array('superuser', 'admin', 'users')); $db->get('users'); // Gives: SELECT * FROM users ORDER BY FIELD (userGroup, 'superuser', 'admin', 'users') ASC; Regular == operator with column to column comparison: // WRONG $db->where ('lastLogin', 'createdAt'); // CORRECT $db->where ('lastLogin = createdAt'); $results = $db->get ('users'); // Gives: SELECT * FROM users WHERE lastLogin = createdAt; $db->where ('id', 50, ">="); // or $db->where ('id', Array ('>=' => 50)); $results = $db->get ('users'); // Gives: SELECT * FROM users WHERE id >= 50; BETWEEN / NOT BETWEEN: $db->where('id', Array (4, 20), 'BETWEEN'); // or $db->where ('id', Array ('BETWEEN' => Array(4, 20))); $results = $db->get('users'); // Gives: SELECT * FROM users WHERE id BETWEEN 4 AND 20 IN / NOT IN: $db->where('id', Array(1, 5, 27, -1, 'd'), 'IN'); // or $db->where('id', Array( 'IN' => Array(1, 5, 27, -1, 'd') ) ); $results = $db->get('users'); // Gives: SELECT * FROM users WHERE id IN (1, 5, 27, -1, 'd'); OR CASE: $db->where ('firstName', 'John'); $db->orWhere ('firstName', 'Peter'); $results = $db->get ('users'); // Gives: SELECT * FROM users WHERE firstName='John' OR firstName='peter' NULL comparison: $db->where ("lastName", NULL, 'IS NOT'); $results = $db->get("users"); // Gives: SELECT * FROM users where lastName IS NOT NULL LIKE comparison: $db->where ("fullName", 'John%', 'like'); $results = $db->get("users"); // Gives: SELECT * FROM users where fullName like 'John%' Also you can use raw where conditions: $db->where ("id != companyId"); $db->where ("DATE(createdAt) = DATE(lastLogin)"); $results = $db->get("users"); Or raw condition with variables: $db->where ("(id = ? or id = ?)", Array(6,2)); $db->where ("login","mike") $res = $db->get ("users"); // Gives: SELECT * FROM users WHERE (id = 6 or id = 2) and login='mike'; Find the total number of rows matched. Simple pagination example: $offset = 10; $count = 15; $users = $db->withTotalCount()->get('users', Array ($offset, $count)); echo "Showing {$count} from {$db->totalCount}"; Subqueries Subquery init Subquery init without an alias to use in inserts/updates/where Eg. (select * from users) $sq = $db->subQuery(); $sq->get ("users"); A subquery with an alias specified to use in JOINs . Eg. (select * from users) sq $sq = $db->subQuery("sq"); $sq->get ("users"); Subquery in selects: $ids = $db->subQuery (); $ids->where ("qty", 2, ">"); $ids->get ("products", null, "userId"); $db->where ("id", $ids, 'in'); $res = $db->get ("users"); // Gives SELECT * FROM users WHERE id IN (SELECT userId FROM products WHERE qty > 2) Subquery in inserts: $userIdQ = $db->subQuery (); $userIdQ->where ("id", 6); $userIdQ->getOne ("users", "name"), $data = Array ( "productName" => "test product", "userId" => $userIdQ, "lastUpdated" => $db->now() ); $id = $db->insert ("products", $data); // Gives INSERT INTO PRODUCTS (productName, userId, lastUpdated) values ("test product", (SELECT name FROM users WHERE id = 6), NOW()); $usersQ = $db->subQuery ("u"); $usersQ->where ("active", 1); $usersQ->get ("users"); $db->join($usersQ, "p.userId=u.id", "LEFT"); $products = $db->get ("products p", null, "u.login, p.productName"); print_r ($products); // SELECT u.login, p.productName FROM products p LEFT JOIN (SELECT * FROM t_users WHERE active = 1) u on p.userId=u.id; Table Locking To lock tables, you can use the lock method together with setLockMethod. The following example will lock the table users for write access. $db->setLockMethod("WRITE")->lock("users"); Calling another ->lock() will remove the first lock. You can also use $db->unlock(); to unlock the previous locked tables. To lock multiple tables, you can use an array. Example: $db->setLockMethod("READ")->lock(array("users", "log"));