Category: 小小草

IT 技术领域学海无涯。其实任何领域都学海无涯,无非 IT 发展太快了,让我有更多嘘唏。希望我掌握的技术有如小小草,虽然渺小,却有旺盛的生命力。

  • Known issues with PDT

    我对 PDT 还不熟,碰到很多问题,都分不清究竟是我不会用,还是 PDT 本身的错。其中一个安装在 Fedora 上的 PDT 已经用了有些日子了,配置被我改来改去,所以更加分不清是谁的错。今天狠狠心,全新下载安装了 PDT Galileo SR1 for win32 版。本来想离 Windows 远一些的,无奈,相对来说,我在 Windows 下用 PDT 比 Fedora 下更久一些,出了问题也更容易定位是什么问题。

    几个小时折腾下来,终于有了结论:

    1. PHP for Windows 本来是集成 odbc 支持的,但 PDT 带来的四个 PHP 解释器不知怎么搞的,就是不支持 odbc,我也不知道去哪里 enable odbc,因为 PHP 手册上说 windows odbc 是内置的。要在 PDT 使用 odbc,那就自己安装一个原版的 PHP 吧。
    2. 在 PDT 下安装 PHP 解释器,对话框有让我填一个 php 启动配置文件,通常是 php.ini。但如果原目录下有一个 php.ini,我想做一个专门用于调试的配置文件,取名叫 php-with-zenddebugger.ini,PDT 根本就不理我填入的文件名,直接去找 php.ini,真是浪费感情。
    3. 既然是自己的 PHP 解释器,ZendDebugger.dll 也得用原版的。当时我图省事,直接把 PDT 带来的 ZendDebugger.dll 拷到我的 PHP 解释器的目录下,不能用,后来比较了原版的,文件大小都相差好多,不知道 PDT 给的是什么版。
  • A good practice in naming rewritten Magento modules

    Magento 里的namespace, module name, controller name, action name, class name, function name, model name, router name, xml identifier name, etc, etc 实在太过复杂,凭我的脑袋实在记不全什么时候该大写,什么时候该小写,什么时候该加一个下划线。

    为了不出错,我尽量照抄 Magento source code,比如 extend Mage_Catalog 模块时,我取名 Myname_Catalog。我这个模块名作前缀重写了一些 Model 和 Block,没遇到问题。最近在重写 Controller 时,出问题了——如用/catalog/product/view/id/1 能执行重写后的 controller;但用/seo-product-page-name.html 却执行了重写前的 controller。这问题不一定是命名引起的,但我在寻找解决方案时意识到要有一个好的命名习惯。

    简言之,网上讨论比较多的 Magento upgrade safe 重写规则只适合 Model 和 Block,不适合 Controller。要写出 upgrade safe Controller 也不难,就是谈的人少,不容易找到适用于最新版 Magento 的文档。有空我整理一下如何在 Magento 1.3 下重写 controller,但这不是我今天想说的话题。

    我只想说我在重写 Controller 时意识到命名习惯。命名时肯定是用自己的 namespace,但也建议不使用原模块名。比如要重写 Mage_Catalog,不妨使用 Myname_Catalogue,这样最大程度地避免了可能的名字冲突。

  • Connect to mdb under Linux

    虽然没有实际意义,只想挑战一下自己,在 centos 下尝试连接 Access 数据库。装好了 unixodbc (原先就在 centos 里,可能是默认被安装的) 和 mdbtools、mdbtools-odbc,搞定了一切设置,可就是出不来。

    我是用 php odbc_connect 去连接 ActinicCatalog.mdb,页面一片空白,连个错误提示也没有,刚开始我还以为 web server 出问题。折腾了好久,最后,自己新建了一个很简单的 mdb 文件,终于在页面上显示出来了。

    总结经验,centos 连接 mdb 需要关闭 selinux,然后,如果页面空白(连跟数据库无关的内容也不显示)不要怪自己,要么怪 mdb 里的结构太复杂,要么怪 mdbtools 能力太弱,读不出来。

    大概只有微软自己知道怎么连接 mdb,第三方是不可能完全读懂它的了。

  • Mybookworld is not safe

    我的 Mybookworld samba service 建有若干用户,各自的目录是凭各自的密码访问。昨天发现,Mybookworld 竟然不再问密码,任由我畅行在各个用户目录。Mybookworld 有一个 ip address 和一个自称的 device name,还有一个路由器指派它的 device name。凭前二者访问仍然正常,只是凭路由器指派的 device name 访问时密码失效。

    我刚开始还以为我上次误点了“记住密码”,运行

    net use * /d

    Mybookworld 还是任由我畅通无阻。奇了怪了,难道 windows 有其他我不知道的地方记住了访问密码?转念一想,不是 windows 的原因,因为我不可能多次为多个用户误点“记住密码”。

    于是重启 Mybookworld,问题依旧。正好有个 firmware 更新,更新后问题还是依旧。没辙了!

    原本准备在 internet 上开放对 Mybookworld 的 ssh 访问,这下打消主意 —— Mybookworld 不够安全,samba 会出这等问题,保不准 ssh 也会出问题。

    别说我是事后诸葛亮,刚拿到 Mybookworld 时,我看了一下它的配置,就觉得它很容易出现安全漏洞。举个例子:用 Mybookworld 自带的 web interface 创建的用户并不是 Linux 用户,这些用户属组全是 root:jewab,使用 root 就是一个非常不好的 bad practice,况且权限控制依赖于 Mybookworld 自带的程序,一点也没用到 Linux 强大的权限控制。开发 Mybookworld 的人水平再高,难道能高到抛弃一套完美的机制自搞一套?

    再举个例子,启用 Mybookworld nfs 服务时可以指定 IP Allowed,但是 /etc/exports 却是这么写的

    /nfs/myname *(rw,all_squash,sync,insecure,anonuid=65534,anongid=65534)

    我非常不理解,nfs 服务明明可以限定 IP,然而 Mybookworld 又不用它,又在自搞一套。可它自搞的一套非常地不稳定,经常发生 allow list 上的用户不许访问。我不知道会不会有 deny list 上的用户反而被允许,那就更糟了。

  • Avoid PEM pass phrase

    我在制作 SSL key file 时输入了一个 pass phrase。CA 把 SSL 证书发给我后,我在 Nignx 试着加载 key 和 证书,发现每次重启 Nginx 时,都会被要求 Enter PEM pass phrase。岂不很烦,而且万一服务器重启,岂不还要人工干预才能重启 web server?

    原本以为把 pass phrase 从 key 文件里拿掉后,要找 CA 重新制作证书,后来发现不用,证书跟 pass phrase 无关。Nginx 的文档没有提及,Apache 倒是有提:

    If necessary, you can also create a decrypted PEM version (not recommended) of this RSA private key with:

    openssl rsa -in server.key -out server.key.unsecure

    拿到 pass phrase 后安全性自然降低了,不过完全值得。

  • It’s time to override Magento controller

    I’m quite happy to override Magento models and blocks. Since overriding controllers is different from overriding models and blocks, I do not want to touch it until recently.

    What I was trying to achieve was a customised product view page which could show different content according to url parameters and login status.

    At first, it was Block detecting url parameters and login status. If the criteria did not meet, Block add an error message and show default content. Then I found this error message would not show up (until next page) because this Block was after Message Block.

    So, for the sake of logic, I have to rewrite the product view controller. And it makes more sense if I conduct a redirect rather than show default content if the criteria do not meet.

  • Zend_Form in Magento

    我喜欢 Zend_Form 这个组件,为了在 Magento 里使用 Zend_Form,走了不少弯路,但最终方法是很简单的。

    要在 Magento 里使用 Zend_Form 最关键的一点是明白 Zend_Form 依赖于 Zend_View,而 Magento 从头到尾都没有用到 Zend_View。如果使用 Zend Framework Bootstrap,它会搭建好 MVC,在你想到去用 Zend_View 之前,它就已经就位了,所以 Zend_Form 在真正的 Zend Framework 里是取之即用的。在 Magento 里,必须自己初始化一个 Zend_View,传递给 Zend_Form 的 $_view,或者用 setView()方法,否则你会得到一个错误提示:ViewHelper decorator cannot render without a registered view object。

    我走的弯路是刻意在 Magento 里照搬 Zend Framework 里 Zend_Form 的输出。我专门建了 views 这个目录,在其下又建了scripts 目录(Magento 里最接近 views/scripts 的目录是 templates,但我不想把 Zend Framework 那套文件与 Magento 的文件混在一起),然后把初始化后的 Zend_Form 赋值给 $view->form,然后在 views/scripts/index.phtml 里

    
    echo $this->form;
    
    

    然后在 Magento 的 Block 文件里新建一个方法

    
    public function getZendView() {
    	return $this->view;
    }
    
    

    最后在 Magento template 文件里

    
    echo $this->getZendView();
    
    

    虽然能运行,但过了一天,我自己都觉得不对头,尝试着直接在 Magento 里输出 Zend_Form,也成功了。具体做法是:

    先为 Zend_Form 创建一个目录,我把它建在 {MyModuleName}/Model 下(我见 Magento 把与 Form 相关的文件归入 Block,但调用 Block 文件没有调用 Model 文件方便。既然如何在 Magento 里使用 Zend_Form 属于我的原创,在不违背 Magento 文件规范的情况下,我应该有自己的自由决定。再说把 Form 对象归于 Model 也不违背 MVC 的原则)。

    然后在其下建了一个 helpers 目录,即 {MyModuleName}/Model/Form/helpers(若不涉及自定义 helper,则跳过此步骤)。选择这个位置,我对自己都有争议,但总得为 Zend_Form 的 ViewHelper 文件找个地方。我在 Zend_Form 里初始化 Zend_View,而 Zend_View 需要知道 ViewHelper 文件的位置,我可以用很简单的dirname(__FILE__) . ‘/helpers’ 得到这个位置。如果放在 Magento 自己的 Helper 目录,则搞混了 Magento Helper 与 Zend ViewHelper,而且我用不着用 Mage::helper(‘mymodulename’) 去调用它。所以我决定在 Form 目录下放置 helpers 目录,以后若把 Form 迁移位置,helpers 也可以随之迁移,方便 refactoring。

    然后创建 Zend_Form,在 Block 里用 $form->render() 得到这个表单的 html 输出,最后在 template 下该怎么做我就不多说了。

  • Administrator name of Mybookworld to downloader area

    如果要登录 Mybookworld downloader,在 Administrator name 那一栏里输入的竟然是 “downloader”。我试了好多次才试正确,每次输错后我气馁地认为 Mybookworld downloader 被 disable 了。我没读 WD 的说明书,这年头谁有耐心看说明书?再说像 network drive 这种东西本来就应该很直观地让人使用,而 Mybookworld 没有做到。

    首先,用 admin 作用户名可以进入 network storage manager 和 copy manager,而进 downloader 非得用 downloader,没有统一规范,我不喜欢;

    其次,downloader 的密码是用 admin 进入 network storage manager 进行修改的,修改完了还要退出 network storage manager 再进入 downloader,烦不烦?

    最后,内置的 admin 和 downloader 用户名不能被修改或删除,给暴力破解提供了方便,安全堪忧。

  • Magento Block has no getters and setters

    I finally realise Block class in Magento is not like Model class – it has no getters and setters.

    It breaks MVC logic if we want to set data in Block, that’s why Block has no setters. However, when Block makes a variable which can be used in template. It is a maker, not a setter. So the function name is usually getSomething(). From the pointer view of template, it is ‘get’, but it is not a getter for Block.

    Magento could name this kind of function in Block something else for people easy to understand.

  • Caveats of firmware upgrade of Mybookworld 1TB

    买了 Mybookworld 2TB,按建议首先做了 firmware upgrade to newest version。

    顺便把原来的 Mybookworld 1TB 也 upgrade firmware,没注意到 Mybookworld 1TB upgrade 以后有没有自启。接着我发现以下反常现象:

    • 原先破解后的 sshd 也失效了,但能按老办法重新破解一遍。
    • 原先注释了 moinet start script,被取消了注释,只好重新注释一遍。
    • 原先修改了 root 的密码被擦除了,幸好 root 没有密码是无法登录的,其他用户的密码还在,赶紧再次修改 root 密码。提示说密码只能 5-8位,其实可以超过8位,把密码弄长一些吧,保险起见。
    • 局域网内其他机子无法凭 netbios name 访问 Mybookworld 1TB,还是手动重启一下 Mybookworld 1TB,以期它能赢得主控浏览服务器选举。