作为程序员一定要保持良好的睡眠,才能好编程

yaf第三课 yaf学习相关文档资料

发布时间:2018-11-15

学习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"));