任氏有无轩改版已经很多次了,从最早的Symfony 1.x开始,在Symfony框架进入到2.x的时候重新改版了一次,最近的这次刚刚结束,也算是很大的一次。
根据我在Bitbucket的提交记录,3月12日开始第一次重新提交,4月22日完成最后一次的提交,历时40余天。但是,众所周知,我的开发是很断续的,平均下来每天投入的时间不会超过1个小时,所以这次改版的总耗时不超过40小时,也就是常规工作时间下一周的工作量——加班的话也就3天左右。
这次的改版牵涉面非常广。
(原文发布于2014年2月5日,原文链接Cursors in MySQL Stored Procedures)
本文收录于[go4pro.org]
====
这篇文章继续了我之前《存储过程》的讨论,专注在讨论Cursor(光标)。这篇的讨论也很热烈。
(原文发布于2014年1月3日,原文链接Stored Procedures in MySQL and PHP)
本文收录于[go4pro.org]
====
我继续着MySQL本身的研究,并讲述了存储过程的概念、优劣和应用。反响非常强烈。
(原文发布于2013年12月30日,原文链接Unique Index and its Rationale)
本文收录于[go4pro.org]
====
这篇文章转移到比较后台的东西:MySQL,特别是数据库中唯一性索引(Unique Index)的使用和隐藏在之后的一些道理,收到了不少反响。
以前我在本机上进行PHP开发和测试用的WAMP组合来自Apache Friends的XAMPP,但是我一直在配置多个VHOST的时候碰到问题,网上搜索也没有什么帮助,所以一直想找个替代品。
2个月前我开始使用来自EasyPHP的EasyPHP Dev Server(当前版本是13.1,VC9,马上会放出需要VC11支持的版本)。
“任氏有无轩”的后台中有一个统计是得出每天对书籍详情页面的访问数量,结果集很简单:一个日期,一个该天的访问次数。
在原生SQL下,这个并不复杂,如下的语句就可以完成: select count(v.bid) vc, date(from_unixtime(v.visitwhen+15*60*60)) vd from book_visit v group by vd order by vd。
但是这个语句稍作变动(将book_visit改为FQN的引用)在SF2中用常规的createQuery将不能执行,提示date函数不被支持。
解决这个问题有两种方法,一种是quick-and-dirty的纯原生SQL:
$q = $em->getConnection()->prepare('select count(v.bid) vc, date(from_unixtime(v.visitwhen+8*60*60)) vd from book_visit v group by vd order by vd');
$q->execute();
return $q->fetchAll();
这个方法简单明了,适合初学者使用。
作为SF2和Doctrine的推荐方法,我们要使用所谓的ResultSetMapping和createNativeQuery。
我们可以这样简单的理解,ResultSetpMapping提供了一种映射机制,将原生SQL返回的字段映射到结果集的域,从而使得Doctrine可以以此构造返回的结果集,然后执行SQL语句,并将结果返回。
应该说,即使你不使用createNativeQuery,而只是用createQuery,Doctrine也还是会隐含的做一个ResultSetMapping的,只是不用显式调用罢了。
代码如下:
public function getVisitCountByDay()
{
$em = $this->getEntityManager();
$rsm=new DoctrineORMQueryResultSetMapping;
$rsm->addScalarResult('vc', 'vc');
$rsm->addScalarResult('vd', 'vd');
$q=$em->createNativeQuery('select count(v.bid) vc, date(from_unixtime(v.visitwhen+15*60*60)) vd from book_visit v group by vd order by vd', $rsm);
$res=$q->getResult();
return $res;
}
这个调用中,最关键的其实是两个addScalarResult。 vc是标量结果很自然,但是vd为什么是标量结果?Doctrine的文档对此语焉不详。
我的理解是,一旦结果集中包含了一个标量结果(vc),那么所有其它结果也自然要变为标量结果。STOP。
本文收录于[go4pro.org]
本文收录于[go4pro.org]。 这两天主要是学习如何将我之前编写的一些jQuery的demo迁移到Titanium里去,采用的编程模式是HTML+CSS+PHP+javascript (jQuery),而不是Titanium本身的UI。
总体来说,过程不复杂,也很直观。大部分代码我只是修改了CSS文件和jQuery文件的位置就可以直接使用了。在这个过程中,有几个地方是我原来认为没有问题,却出了问题的。
首先是连接远程的MySQL。我用的主机是BlueHost,出于安全考虑,BH的主机缺省是不提供远程MySQL的连接的,需要用户加入可信任的IP地址(或地址段)后才可以。
BH提供了一个URI探测客户端的IP,同时在BH控制页面也会探测IP。我发现的第一个问题就是:这两个被探测出来的IP不仅不一样,而且是不对的!如果填入这两个IP,远程连接时还是报错!最终正确的IP是我的路由给出的IP。终于解决了这个问题。
第二个问题就是在Titanium里开始MySQL的连接。之前,我已经在PHP脚本状态编写了一些测试脚本来测试连接,并证明是可以的。但是同样的代码,在Titanium里进行编译并执行后,出现了如下的警告:
Warning: mysql_connect() [function.mysql-connect]: OK packet 6 bytes shorter than expected…. Warning: mysql_connect() [function.mysql-connect]: mysqlnd cannot connect to MySQL 4.1+ using old authentication…. Warning: mysql_select_db() expects parameter 2 to be resource, boolean given….
这些问题的描述其实已经很直观了。在Google中搜索后发现,这个问题的解决需要在我的服务器端对MySQL服务进行配置,当然这个配置在目前我使用的BH主机下是无法实现的。我判断是因为Titanium在编译时使用了一些不正确的参数,并在Titanium论坛里进行了提问,但是到目前还没有回答。
我只能进行另外一种——可能是更正确,因为有“云”的味道——的做法,就是将数据提供部分抽取出来成为一个独立的脚本,然后在客户端脚本中获取返回的数据。具体代码就不提供了,因为不是很困难的代码。
我之所以不用jQuery的json方法获得这些数据,是因为我的客户端PHP脚本需要明确地获得数据后再进行处理。我不能冒异步的风险。
缘起
BT群创建了一个基于status.net的话痨群。我一时手痒,做了个后台,进行一个基本的统计。比如:一天24个时段中每个时段的话痨数量、一周7天中每天的话痨数量等。
这些统计都是要用到基于时间的统计。