这周推翻了之前写的框架,有些代码的确写的lowB了一点。所以打算拿typecho二开做APP的底层。
这几天晚上粗略的看了下typecho的插件开发文档,真tm.....少啊,文档少的可怜。
所以只能四处阅读残缺的文档,结合晚上的一些实验,做些记录
Helper类的应用
Helper类是typecho官方提供的插件脚手架,可以获取系统配置、添加/删除插件,面板,action,和菜单(菜单经测试似乎加不上)
主要的用法
//注册面板
Helper::addPanel(index[索引], '插件名/xxx.php', _t('标题'), _t('标题2'), 'contributor[用户权限]');
//注册路由
Helper::addRoute('路由别名','/xxx/','调用的类名','调用的方法名');
//注册动作 绑定之后 url中带有xxx时,会映射到指定的类上
Helper::addAction('xxx', '调用的类名');
注:
1.关于用户权限可以点此了解
2.Helper还有一个addMenu的方法,但多次测试无效后就不在此推出了,有兴趣的朋友可以自行浏览官方文档
3.以上的方法都有对应的removeAction/removeRoute/removePanel方法,使用方法在此也不过多描述
插件Action的坑
//参考如下代码
//假设我们有一个插件是显示一些物品信息 url为/item/xx(物品id)
//此时该url会触发Item_Action类的action方法,但新手们可能会发现无法获取到id的值
Helper::addRoute('show','/item/[id:digital]','Item_Action','action');
昨天晚上遇到这个问题,无论输出$_GET(结果为空数组)也好,还是使用Typecho_Request::get()也好,都获取不到id的值。
于是仔细查看typecho的源码,追踪到了 /var/Typecho/Route.php
try {
/** 载入参数 */
$params = NULL;
if (!empty($route['params'])) {
unset($matches[0]);
$params = array_combine($route['params'], $matches);
}
//$params被传送到了这里
//大概的语句应该是这样
//Typecho_Widget::widget('xxx_Action',NULL, ['id'=>7]);
//
//那我们去看看 Typecho_Widget::widget 到底做了什么
$widget = Typecho_Widget::widget($route['widget'], NULL, $params);
if (isset($route['action'])) {
$widget->{$route['action']}();
}
return;
} catch (Exception $e) {
if (404 == $e->getCode()) {
Typecho_Widget::destory($route['widget']);
continue;
}
throw $e;
}
打开 /var/Typecho/Widget.php
public static function widget($alias, $params = NULL, $request = NULL, $enableResponse = true)
{
$parts = explode('@', $alias);
$className = $parts[0];
$alias = empty($parts[1]) ? $className : $parts[1];
if (isset(self::$_widgetAlias[$className])) {
$className = self::$_widgetAlias[$className];
}
if (!isset(self::$_widgetPool[$alias])) {
/** 如果类不存在 */
if (!class_exists($className)) {
throw new Typecho_Widget_Exception($className);
}
/** 初始化request */
if (!empty($request)) {
$requestObject = new Typecho_Request();
$requestObject->setParams($request);
} else {
$requestObject = Typecho_Request::getInstance();
}
/** 初始化response */
$responseObject = $enableResponse ? Typecho_Response::getInstance()
: Typecho_Widget_Helper_Empty::getInstance();
/** 初始化组件 */
//看这里,widget方法创建了一个新的组件,并且传入request对象,response对象和参数
//request和response都是对应基类的实例,所以可以直接调用对应的方法
$widget = new $className($requestObject, $responseObject, $params);
$widget->execute();
self::$_widgetPool[$alias] = $widget;
}
return self::$_widgetPool[$alias];
}
那么到此整个疑问就已经解开了,我们在xxx_Action类中创建一个构造方法接收对应的对象即可
class Shop_Action implements Widget_Interface_Do
{
private $request;
private $response;
private $params;
public function __construct($request,$response,$params){
$this->request = $request;
$this->response = $response;
$this->params = $params;
}
public function action(){}
}
到此我们就可以使用 $this->request->id 接收对应的值了。
数据库查询如何使用IS NULL
也不知道是不是我的需求太小众,居然在typecho的文档和问题中找不到我想要的答案,于是只能自己翻源码
需求:查询文章中不带访问密码的文章
方法:数据库查询时查询 password字段为空 的文章
因为这个问题的关注点在于where()方法上,于是根据类层层找where()所处的文件(别问我为什么不用phpstorm直接找,用的在线编辑器 心塞)
首先找到 Typecho_Db 基类的位置 /var/Typecho/Db.php 因为查询用的是select方法,所以查看该类的select().
public function select()
{
$args = func_get_args();
//select用到了本类中sql()方法,去看下sql()
return call_user_func_array(array($this->sql(), 'select'), $args ? $args : array('*'));
}
//sql方法又返回一个Typecho_Db_Query类实例,那么我们再去看下Typecho_Db_Query
public function sql()
{
return new Typecho_Db_Query($this->_adapter, $this->_prefix);
}
Typecho_Db_Query 在 /var/Typecho/Db/Query.php,嗯,找到where方法了
public function where()
{
$condition = func_get_arg(0);
$condition = str_replace('?', "%s", $this->filterColumn($condition));
$operator = empty($this->_sqlPreBuild['where']) ? ' WHERE ' : ' AND';
if (func_num_args() <= 1) {
//注意这里,当where只有一个参数时,则直接当成字符串拼接
$this->_sqlPreBuild['where'] .= $operator . ' (' . $condition . ')';
} else {
$args = func_get_args();
array_shift($args);
$this->_sqlPreBuild['where'] .= $operator . ' (' . vsprintf($condition, $this->quoteValues($args)) . ')';
}
return $this;
}
到了这里一切都很明了了,我们对于使用IS NULL方法,直接使用where('xxx IS NULL')即可
使用where('xxx = ?',NULL) 或 使用where('xxx IS ?',NULL)都会报错!
本文由 程序哩 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Jan 11, 2019 at 12:12 pm