无耻的腾讯

无耻的腾讯
kuhanzhu说这叫广播不叫广告,我无语了…

上个月因为有需要创建多个群,才付费成为了QQ会员

按照腾讯的声明,QQ会员是可以过滤腾讯的广告的,但是即使你选择了过滤广告,腾讯还是时不时给你发来些广告

哎,不知道怎么说好,腾讯啊腾讯,你怎么能无耻到这种地步

Oracle LOB字段在PHP PDO_OCI下的解决方法

在我们的项目中,使用了Oracle做为数据库,PDO_OCI 作为数据库驱动。

项目中需要使用到CLOB字段来存储大量的数据,什么CLOB?我们先来看看Oracle官方的说明

Oracle 提供了以下 LOB 类型:
* BLOB,用于存储二进制数据
* CLOB,用于使用数据库字符集编码存储字符数据
* NCLOB,用于使用国家字符集存储 Unicode 字符数据。 注意,您将在本文中使用的 PHP OCI8 扩展当前不支持 NCLOB。
* BFILE,用于引用存在于操作系统的文件系统中的外部文

在PHP中,如果你想把LOB字段当做普通的字段来存取数据,会导致程序出错,甚至包括 httpd.exe 的非法错误。PHP的 OCI8 扩展提供了这一字段的支持,但仅提供了 BLOB、CLOB、BFILE 三种类型字段的支持(使用方法请参考Oracle官方文档),但 PDO_OCI 并没有提供这样的支持,那么我们如何解决这个问题?

通过查询相关文档找到了以下的解决办法,由于项目中使用了 Zend_Framework,那么我就以 Zend_Framework 来解决问题,关于 PHP 中的使用方法请参考PHP手册 PDO Functions - Large Objects (LOBs) 一节:

$stmt = new Zend_Db_Statement_Pdo($db, $sql);
$stmt->bindColumn('CONTENT', $content, PDO::PARAM_LOB);
$stmt->bindColumn('TITLE', $title, PDO::PARAM_STR);
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_BOUND)) {
    
echo '<h1>' . $title . '</h1>';
    
echo stream_get_contents($content) .'<hr />';
}

这里,使用到了 PDOStatement->bindColumn() 的方法,参阅相关资料得知:PDO::PARAM_LOB 可用于大文本对像字段,并使用 PDO::FETCH_BOUND 模式来进行存取,这是关于 PDO::PARAM_LOB 的说明:

PDO::PARAM_LOB (integer)
Represents the SQL large object data type.

这样的方法需要要求我们对所需要存取的字段都进行绑定,因此在例子中还使用了 PDO::PARAM_STR,但是那将会是一件非常烦琐的事。因此在项目中我们使用了 OCI8 的扩展来完成工作,这样工作变得简单很多,这也是Oracle官方给出的使用方法,取出数据时用到了一个 load() 的方法,至于更详细的用法就不在这里啰嗦了,大家可以自己参考一下文档。

相关的 Zend_Framework 代码如下:

$stmt = new Zend_Db_Statement_Oracle($db, $sql);
$stmt->execute();
while ($row = $stmt->fetch(Zend_Db::FETCH_ASSOC)) {
    
echo '<h1>' . $row['TITLE'] . '</h1>';
    
echo $row['CONTENT']->load() . '<hr />';
}

显然,上面的方法要方便很多。

另外,Zend Framework 对 Oracle 的 OCI 驱动的 lastInsertId (sequence) 的BUG还没有修正,如果大家在使用中出现问题,请找到 Zend_Db_Adapter_Oracle 第218行的 $sequenceName .= ‘_seq’; ,修正为 $sequenceName .= ‘_SEQ’; 即可(PS:这里需要大写,也不知道他们到底有没有做过测试,估计是没有的)。

口误笑话 @_@~

1 单位祝词,一位领导说:“祝大家身体愉快……”憋住,没词了。

2 有一次帮老板订酒店,想问问人家有没有什么免费上网之类的服务,却怎么也想不出来怎么说好,于是就问对方:“请问,你们这里有什么特殊服务吗?“
对方:“什么?特殊服务??我们是正规酒店!”
-__-!!!!

3 宿舍老四下床找了半天拖鞋,没有,问大家:为什么我的拖鞋哪里去了?

4 逛街中,突然朋友惊呼:“哇!‘处女书店’!”我大惊,抬头一看,一块匾额,上书四个大字
——外文书店-__-!

5 我有次去买羊肉串
伸出4个手指对老板说“来3根羊肉串”
老板蒙了“几根?”
我又伸出3个手指说“4根”……

6 我们的总经理姓周,一次他打电话来,我正开车,一紧张张口就说:”周总理……”

7 本人姓朱,管理单位机房。有次有人打我手机:“鸡科长,你在猪房吗?”当时狂骂那家伙一顿

8 在食堂排队,听见旁边一男生说:“师傅,来碗‘子弹菜花’汤!”(紫菜蛋花汤)哈哈,笑得我喷汤了。

9 某日在米线店吃饭上得很慢很饿
终于按耐不住拍桌咆哮之,本来是想说再不上米线我就把桌子掀了!
结果说成:”老板!!!!再不上米线我就把桌子吃了!!!!”
全店沉默3秒后爆笑到桌子下面……丢人……

10 爸妈吵架,我爸气的说了句:”我给你滚出去!”

11 高中的时候打篮球,A得球后,无私的传给了B,B轻松进球.过了一会,B得球,A大声喊着把球传给他.B却自己把球投出.结果A大怒喊到:刚才真是瞎了我的狗眼……
全场笑晕

12 印象里小学时的班长极其严肃,一次自习课,教室里人声鼎沸,班长维护了几次秩序之后终于忍无可忍,站起来一拍桌子怒吼道:谁再吵,把他嘴打断!!!……全班肃静

13 大学的时候,我们问一个哥们曼联的战况如何,他激动的说:“曼联输了,贝克汉姆领到两张黄盘下场了!”

14 没有金箍棒就别揽瓷器活

15 上大学时,一老师讲课,讲到一种新型的材料,说:“这种材料的性功能是旧材料不可比拟的……啊不对,性能和功能……”

16 刚上大学,军训,连长不知道是哪里的口音,喊口令——“向左钻!”“向右钻!”
(未完,点击阅读全文)

好用的数据库管理软件 — DbVisualizer

这是在查找Oracle客户端工具时找到的一个软件,使用JAVA开发的,目前拿他来做Oracle、MySQL、PostgreSQL甚至包括 MS SQL Server 数据库管理都是一件非常轻松的事情,官方网站为:http://www.dbvis.com/products/dbvis/

目前最新版本为6.0,不过我使用的是5.0,大家可以在官方网站申请试用,试用时间为20天。(PS:网上流传有5.0的Crack文件,大家可以去找找)

个人还是比较喜欢这种GUI的管理方式,特别是可以轻松生成E-R图并导出,所以决定以后都使用放弃 phpMyAdmin。

以下是我的BLOG程序数据库E-R图,怎么样,还不错吧。
Tblog E-R 图

不过创建连接之前需要下载 JDBC 的jar包,基本上都是使用 jdbc 的方式来建立连接的,相关包大家可以到官方网站下载:http://www.dbvis.com/products/dbvis/drivers.html

DbVisualizer添加JDBC驱动程序的步骤:
1. 选择Database菜单。
2. 选择DriverManager 菜单项。
3. 选择Add new driver location 工具栏菜单项。
4. 选择mysql-connector-java-3.0.9-stable-bin.jar。

创建MySQL数据库连接:
1. 选择Database菜单。
2. 选择 Add Database Connection菜单项。
3. 指定连接别名 (如 sem)。
4. 在下拉列表中,把JDBC驱动选择为com.mysql.jdbc.Driver。
5. 在下拉列表中,把数据库URL选择为 jdbc:mysql:///
6. 将URL修改为个人的地址,输入用户名和密码,连接建立完毕

对于具体的细节,大家自己去体验了,非常强大的功能界面,感觉操作方式及设计上还是比较人性化的,顺便截两张界面图,分享一下

3.jpg

2.jpg

1.jpg

开始开发个人BLOG程序 - TBlog

今天晚上睡得早了点(一点多睡的),结果睡了几个小时睡不着,于是爬起来喝点啤酒~~突然想到一直想写个自己的BLOG程序,于是决定利用 Zend Framework 做开发,编写个人的 BLOG 程序。花了点时间,把基础的环境搭建起来先,感谢星星为我提供 SVN 空间。

SVN 地址为:svn://www.i-fang.com/Akon

目前仅对入口文件及一些简单的操作进行了封装,有兴趣的朋友可以看一下。

不过估计不会花太多时间在这上面,因为项目也比较紧,加上最近准备花大把时间学习C,所以开发进度可能会比较缓慢,不过算啦,有时间就写一点,相信总会写完的。

琼瑶《又见一帘幽梦》的经典台词

今天看一新闻文章时看到的一段,觉得有点意思,给大家分享一下

1、紫菱说巴黎铁塔没什么了不起:它从前面看是一座铁塔,它从后面看是一座铁塔,它从左面看是一座铁塔,它从右面看是一座铁塔,它从上面看是一座铁塔,它从下面看还是一座铁塔……

2、紫菱:云帆,我晕车耶!

云帆:怎么会晕车呢,这只是马车呀。是不是中暑了?有没有发烧?

紫菱:我不是那种晕车!我是坐着这样的马车,走在这样的林阴大道上,我开心得晕了,陶醉得晕了,享受得晕了,所以,我就晕车了。其实,我自从来到普罗旺斯,就一路晕。我进了梦园,我晕。我看到了有珠帘的新房,我晕。到古堡,我晕。看到种熏衣草的花田,我还是晕。看到山城,我更晕。反正,我就是晕。

云帆:好,你晕吧,我在你身边,如果你晕倒了,我会抱住你。

指出某人一些解答错误的地方及XX框架的不足

由于ZF1.0的发布,导致最近与某些人在在PHPChina上大打口水战,很是不爽。

今天在看某一论坛XX人的解答时,发现了不少个人认为是解答错误的地方,特来指出一二,如果觉得我说得有错的,欢迎指教。

另外也针对一下XX人一直认为“特别”优秀的框架做一些简单的对比。

1、关于Join会降低效率,使用“递归关联查询”提高效率
参考:http://www.fleaphp.org/bbs/viewt … p;extra=page%3D1### 四楼

QUOTE:
1、不同对象的职责更明确;
2、尽量减少不必要的 join,显著提高查询效率;
3、可以在递归关联查询时,获得更多的灵活性。

1、首先我不明白什么是“递归关联查询”,我搜篇了Google没发现有这个名词,估计乃XX人所独创,实在是强。
2、如果“递归关联查询”是指“递归查询”的话,不知道有谁听过“递归关联查询”比JOIN更快的方法。
3、从来只听说过使用JOIN的方法来提高查询效率,生平第一次听说JOIN会使效率降低,实在感叹自己像XX人所说“井底之蛙”,不知道XX人是否知道什么叫做笛卡尔乘积?
   一些参考:http://dev.mysql.com/doc/refman/ … t-join-optimization
                    http://edu.cnzz.cn/NewsInfo/29612.aspx
4、至于说到JOIN在查询大量数据时会降低效率,这不能说明什么,只用一个select查询表和多表关联查询时能快多少?
   不知道有没有谁的项目是会在一个页面中显示上百条记录的数据的,我想很少,那么这个效率已经缩小了。
5、JOIN真的会慢很多吗?
   当JOIN的驱动表(应该是一个结果集比较小的表)对另一个表做查询时,表中最多只有一行匹配的记录,它在查询一开始的时候就会被读取出来。 由于只有一行记录,在余下的优化程序里该行记录的字段值可以被当作是一个恒定值。MySQL在查询时做一个 LEFT/RIGHT JOIN 优化时,当它在当前表中找到了和前一条记录符合 LEFT JOIN 条件后,就不再搜索更多的记录了。
   由上可见,当驱动表较小的时候,使用JOIN做查询的时候,是会超过其他的方式的(当然不包括单表的SELECT)。当然JOIN确实也是会降低效率的,因为他要花很多的功夫在对数据的排序操作上,但当驱动表变小的时候,这一性能上的消耗几乎可以忽略不计。除非有人硬是要在一个页面上取出成百上千条记录,但我想这个时候要还没建视图,我想这家伙也够笨了,如果有人认为还有比视图查询更快速的查询方法,麻烦提出来,其实JOIN不就是一个逻辑上的视图吗?

2、建议手写 SQL 作为 $conditions,这样效率非常高,而且再复杂的条件都可以使用
参考:http://www.fleaphp.org/bbs/viewt … &extra=page%3D1
1、这是一个多么幼稚建议啊,稍稍复杂一点就要都手写SQL语句了,那我还要框架干嘛呢?
   殊不知被人称为丑陋的 Zend_Db_Select 在这上面就非常好用,添加几段类似如下的代码,由ZF本身对几个字符串组合一下就能生成正确的SQL语句,这样已经大大减少了写SQL语句的工作,对于一个项目来说,少写许多SQL语句对于开发效率来说会是一个多大的提升啊。
   (PS:不知道是不是因为ZF要组织一下字符串生成SQL,而使某人觉得这样消耗了性能还是其他,如果是这样我也无话可说了)


$select $db->select();
$select->from(….)
       ->
where(….)
       ->
where(….)
       ->
where(….)
       …; 


看上面的代码,多么容易阅读和扩展啊?居然有人说这是垃圾,真搞不懂,哎~~~

3、可以给 $dbo 增加两个属性:activeDb 和 defaultDb,分别指示当前操作的数据库和该 $dbo 原本要操作的 数据库
参考:http://www.fleaphp.org/bbs/viewt … &extra=page%3D1
不知道XX人听说过 Database Schema 这个东西没有,我很庆幸我正在使用中的 Zend Framework 提供了这个功能,非常方便且好用,至少不需要像XX人提出的建立多个连接来进行操作了。
(PS:我之前在某文中提到的框架局限性中非常严重的包括了这一部分的问题)

总结:看了看XX框架的代码,看了看某人对数据库的了解,感觉这个框架在DB这方面的设计思路上似乎有些问题,可能效率不是很好,不过还没做数据测试,暂时不下定论,明天抽个时间做个测试吧。另外,XX框架号称支持Oracle,殊不知在Oracle中根本没法使用,因为作者似乎不知道 Database Schema 是一个非常重要的东西,相信框架的作者并没有在Oracle上做太多的测试就发布了,让人用起来有点心惊胆战的。

Zend_Auth部分代码示例

protected $_auth;
    protected $_userId;
    protected $_userName;

    public function init()
    {
        $this->_auth = Zend_Auth::getInstance()
             ->setStorage(new Zend_Auth_Storage_Session(‘authNameSpace’);
    }

    public function indexAction()
    {
        if ($this->_auth->hasIdentity()) {
                $this->_userId = this->_auth->getStorage()->read()->USER_ID;
                $this->_userName = $this->_auth->getStorage()->read()->USER_NAME;
            echo ‘登陆成功’;
        } else {
            $this->_forward(‘login’);
        }
    }

    protected function _logout()
    {
        $this->_auth->clearIdentity();
        Zend_Session::forgetMe();
    }

    public function loginAction()
    {
        if ($this->isPost()) {
            $f = new Zend_Filter_StripTags();
            $username = $f->filter($this->getPost(‘username’));
            $password = $f->filter($this->getPost(‘password’));

            //建立认证适配器 (DB适配器名/表名/用户名字段/密码字段)
            $authAdapter = new Zend_Auth_Adapter_DbTable($this->_db);
            $authAdapter->setTableName(‘USER’)
                        ->setIdentityColumn(‘USER_NAME’)
                        ->setCredentialColumn(‘USER_PASSWORD’)
                        ->setIdentity($username)
                        ->setCredential(md5($password));
            $result = $this->_auth->authenticate($authAdapter);

            //建立持久连接
            if ($result && $result->isValid()) {
                if ($this->getPost(‘rememberMe’)) { //记住密码
                    Zend_Session::rememberMe(‘315360000′);
                } else {
                    Zend_Session::forgetMe();
                }
                $this->_auth->getStorage()->write($authAdapter->getResultRowObject(array(‘USER_ID’, ‘USER_NAME’)));
                $this->_forward(‘index’);
            } else {
                echo ‘登陆失败’;
            }
        }
    }

继续FB,070610广州PEA烧烤聚会

恰好这一天是星星的生日,中午和阿标、macoo、frank几个人小聚祝星星生日快乐,然后一帮人去超市买些东西为下午的烧烤做准备。

老天爷很争气,下了好多天雨的广州突然不下雨了。

只可惜最近身边的朋友似乎都不怎么走运,一住深圳布吉的同事家里被盗,损失了近2万多元,最惨的是几年积累下来的代码全都丢失,这个损失是无法估计的。在从深圳去广州的路上,同事macoo居然把钱包弄丢了,损失了500多元还有许多的证件和银行卡,包括身份证… 我只能同情一下了,各位出门在外的朋友也要小心一下。

点击这里查看更多聚会照片…

6月3日大鹏湾游玩

6月3日,公司全体开发人员+股东及家属一起到大鹏湾游玩,天气非常晴朗,非常清爽,海水也非常蓝,上午9点半出发,在一个滨海的小村庄里吃了午饭后就径直前往海滩边上。

由于这里是个半岛,海水也变得非常咸,大家在游泳的时候都被呛到不行。其实大家都拍了不少照片,但是我的由于蓝牙坏了,无法导出手机中的照片,因此照片的数量也比较有限,不过也已经够了。

要查看更多的照片可以点击这里,查看到我的相册


9点半出发,一小时后看到了大海,但这里不是我们的目的地


远远的看到,大海很蓝很蓝,天空很晴朗,这是一个好天气


12点左右终于到达目的地,这里人不是很多。这里相对比较偏僻,人也比较少,查看地图后知道这里是个半岛,比较靠近海中心,因此海水也相对咸很多,大家也都有点不太适应,我也被呛得可以,喝了好多海水

Theme Brought to you by Directory Journal and Elegant Directory