分类 WEB开发 下的文章

SinglePHP 微框架

  SinglePHP是之前看到一个百度的朋友SinglePHP框架,个人比较感兴趣,于是对整个框架进行了深度修改(Deep modified)。并且放到了Github:https://github.com/nly/SinglePHP,里面有详细的文档和实例。非常欢迎大家参与进来,一起开发。

A simple but powerful php framework.

说明:

  1. 首先是vhost、rewrite配置

    Apache:

    <VirtualHost *>

    DocumentRoot "your/path/to/htdocs"
    ServerName single.dev.com
    ServerAlias www.single.dev.com

    </VirtualHost>

    <IfModule mod_rewrite.c>

    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]

    </IfModule>

    Nginx:

    location / {

    if (!-e $request_filename) {
        rewrite ^/(.*)$ /index.php last;
        break;
    }

    }

    1. 目录结构

         root
            |
            |---SinglePHP.class.php
            |---htdocs---|
                         |--index.php
                         |--.htaccess
                         |--favicon.ico
            |---app---|
                      |---config     配置文件夹
                      |---controller 控制器文件夹
                      |---dts        数据传输对象
                      |---dw         数据写入
                      |---dr         数据读取
                      |---lib        类库
                      |---tpl        模板目录
                      |---widget     widget
                      |---tool       工具
                      |---common.php 通用函数库
                      
            |---logs-- 日志目录 .wf为错误日志,.log为普通日志
      
    1. 访问路径

         f.e:
         single.dev.com                      --->    app/controller/index.php ->  _run()
         single.dev.com/index                --->    app/controller/index.php ->  _run()
         single.dev.com/index?id=123         --->    app/controller/index.php ->  _run() 
         single.dev.com/start                --->    app/controller/start.php ->  _run()
         single.dev.com/doc                  --->    app/controller/doc.php   ->  _run()
         single.dev.com/event/prize          --->    app/controller/event/prize.php ->  _run()
         single.dev.com/event/mobile/index   --->    app/controller/event/mobile/index.php
          ->  _run()
         
    2. 如何使用类?

         一般来说,不需要显示的实例化。
         f.e:
         namespace Controller
         {
             class Index extends Base
             {
                 public function _run()
                 {
                     echo "hello world";
                     echo testFunction();
                     new \Dw\Event();
                     \Dw\Event::add();
                     $this->display();
                     //$this->display('index');
                 }
             }
         }
         
         namespace Controller\Event
         {
             class Prize  extends \Controller\Base implements \Controller\Inter\Test
             {
                 public function _run()
                 {
                     $this->add();
                     $this->del();
                     $this->modify();
                 }
      
                 public function add()
                 {
                     echo 'add';
                 }
      
                 public function del ()
                 {
                     echo 'del';
                 }
      
                 public function modify()
                 {
                     echo 'modify';
                 }
             }
         }
         

      5.如何命名?

        类名完全是和目录对应的
        
        f.e:
            Controller\Index ----> 及就是 controller 下的 index.php
            Controller\Base  ----> 是controller下的base.php
            Controller\Interface\Interface  ---> 是controller下interface下的interface.php
            Controller\Event\Mobile\index   ---> 是controller下event目录下mobile下的index.php
            \Dw\Event   -->  是 dw下的event.php
        反正大概就是这样子的,目录名,文件名都是小写,namespace。
    

    6.注意事项:

    模板中如果使用php代码,并且使用了模板压缩功能,那么"<?php"后面请输入一个空格,并且不能换行,
    并且必须带有"?>"的结尾.
    f.e:
        <?php $data = array(
            'title' => 'Welcome',
            'body_class' => 'bs-docs-home',
        );
        \Single\View::tplInclude('public/header', $data);
        ?>

    使用gdb调试php扩展

    我们在工作中可能会遇到使用别人的或者自己开发的php .so扩展的时候出一些莫名其妙的错误,因为这些错误是底层级别的,我们看不见,那怎么来调试并发现这些C层面的错误呢?这时候就需要使用gdb(GNU Debugger)了。我们先去http://ftp.gnu.org/gnu/gdb/ 下载最新版的gdb,然后编译安装。

    启动调试:

    > gdb /path/to/php //指定您php所在的路径
    > run test.php //您要调试的php文件,要包含出错的地方

    接着应该就可以看见php的执行中有错误的地方了。

    但是在osx下会出现这个问题:

    Starting program: /Users/username/ws/hello
    Unable to find Mach task port for process-id 358: (os/kern) failure (0x5).
    (please check gdb is codesigned - see taskgated(8))

    提示以上gdb签名错误。

    原因是:

      Darwin kernel出于安全考虑,在没有特殊授权的情况下不允许gdb调试任何程序,因为可以调试就掌握了进程的控制权。不过如果是root用户就没有这个问题,不过一般不会用root来调试程序。

    解决方法:

      一个常用的解决方法就是给gdb授予系统完全信任的代码签名权利,以对其他进程。

    首先,需要创建一个系统代码签名信任证书:

    1、启动“钥匙串访问”应用(/Applications/Utilities/Keychain Access.app)

    2、打开菜单:钥匙串访问->证书助理->创建证书...

    3、输入证书名称,如:gdb-cert;

    4、选择身份类型:自签名根证书 (Identity Type to Self Signed Root)

    5、选择证书类型:代码签名 (Certificate Type to Code Signing)

    6、勾选:让我覆盖这些默认签名 (select the Let me override defaults)

    7、一路继续,直到选择存放证书地址,选择:系统

    8、这样证书就创建好了,还要设置证书自定义信任

    9、右键刚才创建的 gdb-cert 证书,选择“显示简介” (Get Info)

    10、点击“信任”,会显示可以自定义的信任选项

    11、“代码签名”选择“总是信任” (Code Signing to Always Trust)

    其次,将证书授予gdb,执行命令

    >codesign -s gdb-cert /path/to/gdb  // 一般在/usr/local/bin/gdb
    

    注意,需要先退出“钥匙串访问”应用,或者重启下系统

    好了,以上就给gdb授予了系统信任的代码签名证书,可以正常使用gdb了。

    注意:前提是 php -m 中 包含了您要调试的那个扩展。

    我们还可以用

    nm /path/to/xxx.so 来查看这个扩展中包含了哪些函数。

    然后使用 gdb > break function_xxx 来设置这个函数的断点。

    然后使用 gdb > bt 来查看具体的错误上下文信息。

    解决Seaslog在osx10.9.4 make错误

      昨天又看见了Seaslog发新版的消息,作为作者的朋友,心想还是试试看吧,于是下载了源代码过来编译安装。地址:http://pecl.php.net/get/SeasLog-1.1.0.tgz

    不料在make的时候出现了一下错误:

    /Users/leandre/SeasLog-1.1.0/SeasLog/seaslog.c:196:6: error: conflicting types for 'seaslog_init_buffer'
    void seaslog_init_buffer(TSRMLS_D)
    /Users/leandre/SeasLog-1.1.0/SeasLog/seaslog.c:208:6: error: conflicting types for 'seaslog_clear_buffer'
    void seaslog_clear_buffer(TSRMLS_D)
    

    剩下还有很多的warning就不贴出来了。

    主要原因就是C99不建议隐含定义函数,太容易出错了。

    解决方案:在·Seaslog.c·的42行的

    42 void seaslog_init_logger(TSRMLS_D);
    

    后面添加以下代码:

    void seaslog_init_buffer(TSRMLS_D);    
    void seaslog_clear_buffer(TSRMLS_D);    
    int _ck_log_dir(TSRMLS_DC);    
    int _seaslog_log_content(TSRMLS_DC);    
    int _seaslog_log(TSRMLS_DC);    
    int _check_level(TSRMLS_DC);    
    int _mk_log_dir(TSRMLS_DC);    
    int _php_log_ex(TSRMLS_DC);
    

    去定义这些函数满足C99的标准,就OK了。

    PS:新版的1.1.4已经解决这个问题并发布:http://pecl.php.net/get/SeasLog-1.1.4.tgz