• 2016-08-19

    集成于 iphp 框架的 PHP 并发模型和工具

    Views: 5909 | 2 Comments

    由于 PHP 具有"所思即所写"的强大优势, 使其在 Web 之外, 也被广泛用于后台脚本编写. 而且, 当你已经用 PHP 来开发 Web 应用时, 你显然不愿意再引入 Java 或者 Python 等语言, 再说, 这些语言相对 PHP 的强大优势, 显示太弱了.

    不过, 用 PHP 来编写后台脚本, 也有一些劣势, 那便是 PHP 缺少并发模型. 例如, 当你用 HTTP 请求第三方服务, 而第三方每一个请求要处理 10 秒时, 这就需要你并发地发起请求. curl_multi 当然能处理, 但不通用, 而且对代码逻辑的改变太大, 需要从串行化改为批量化, 对思维干扰太大.

    为此, PHP 提供了一套 Master-Workers 并发模型, 帮助你实现 PHP 的并发处理.

    Continue reading »

    Posted by ideawu at 2016-08-19 14:29:36
  • 2016-06-23

    PHP过滤掉Emoji表情字符

    Views: 6167 | 1 Comment

    这段代码在 stackoverflow 上搜到, 据说是 Smarty 用的.

    function smarty_modifier_emojistrip($string)
    {       
        return preg_replace('/\xEE[\x80-\xBF][\x80-\xBF]|\xEF[\x81-\x83][\x80-\xBF]/', '', $string);
    }
    
    Posted by ideawu at 2016-06-23 15:53:56
  • 2016-02-25

    PHP 用 curl 读取 HTTP chunked 数据

    Views: 6725 | No Comments

    对于 Web 服务器返回的 HTTP chunked 数据, 我们可能希望在每一个 chunk 返回时得到回调, 而不是所有的响应返回后再回调. 例如, 当服务器是 icomet 的时候.

    在 PHP 中使用 curl 代码如下:

    <?php  
    $url = "http://127.0.0.1:8100/stream";
    
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'myfunc');
    $result = curl_exec($ch);
    curl_close($ch);
    
    function myfunc($ch, $data){
        $bytes = strlen($data);
        // 处理 data
        return $bytes;
    }
    

    但是, 这里有一个问题. 对于一个 chunk, 回调函数可能会被调用多次, 每一次大概是 16k 的数据. 这显然不是我们希望得到的. 因为 icomet 的一个 chunk 是以 "\n" 结尾, 所以回调函数可以做一下缓冲.

    function myfunc($ch, $data){
        $bytes = strlen($data);
        static $buf = '';
        $buf .= $data;
        while(1){
            $pos = strpos($buf, "\n");
            if($pos === false){
                break;
            }
            $data = substr($buf, 0, $pos+1);
            $buf = substr($buf, $pos+1);
    
            // 处理 data
        }
    }
    
    Posted by ideawu at 2016-02-25 16:44:11
  • 2016-02-16

    iphp 框架增加 lazyload 特性

    Views: 5401 | No Comments

    基类中为了方便原则, 一般会加载所有可能用到的属性到 Context 中, 但这会导致性能问题, 所以需要 lazyload 机制. 例如, 某些属性只有在子类中被用到时, 才会真正地去查询数据库, 如果子类中不使用这些属性, 则不会发生数据库请求.

    原型:

    Context::lazyload($name, callable $callback_func);
    

    示例:

    class AppController extends Controller
    {
        function init($ctx){
            parent::init($ctx);
            $ctx->lazyload('account', array($this, 'ctx_lazyload'));
        }
    
        private function ctx_lazyload($name, $ctx){
            if($name == 'account'){
                return Account::get($ctx->user->id);
            }
        }
    }
    
    Posted by ideawu at 2016-02-16 11:41:54
  • 2015-05-07

    PHP 解码 C 字符串

    Views: 13182 | 2 Comments

    有时候, 需要将 C 语言字符串字面量编码的字符串转换成其在内存中实际的值, 如果用 Python, 是有内置的函数, 但 PHP 没有, 只能写一个.

    C 语言字符串字面量编码, 就是类似:

    \r\n\x90
    

    它们在内存中肯定不是这样.

    完整代码如下, 需要 PHP 5.4+.

    function unescape_c_str($str){
        $ret = '';
        $len = strlen($str);
        for($i=0; $i<$len; $i++){
            if($str[$i] != '\\'){
                $ret .= $str[$i];
                continue;
            }
            $i++;
            switch($str[$i]){
                case 's':
                    $ret .= ' ';
                    break;
                case 'a':
                    $ret .= "\a";
                    break;
                case 'b':
                    $ret .= "\b";
                    break;
                case 'f':
                    $ret .= "\f";
                    break;
                case 'v':
                    $ret .= "\v";
                    break;
                case 'r':
                    $ret .= "\r";
                    break;
                case 'n':
                    $ret .= "\n";
                    break;
                case 't':
                    $ret .= "\t";
                    break;
                case '\\':
                    $ret .= "\\";
                    break;
                case 'x':
                    $hex = substr($str, $i+1, 2);
                    $ret .= hex2bin($hex);
                    $i += 2;
                    break;
                default:
                    $ret .= $str[$i];
                    break;
            }
        }
        return $ret;
    }
    
    Posted by ideawu at 2015-05-07 12:51:28
  • 2015-03-10

    使用 SSDB 来实现操作频率限制

    Views: 45245 | 5 Comments

    在 Web 开发中, 经常需要实现操作频率限制的功能, 以避免单个用户过度地消耗某项资源, 或者消除安全隐患. 例如, 限制某 IP 刷新页面的频率, 限制一个用户投票只能投一次, 等等.

    要实现操作频率限制, 就要用到存储. 使用 SSDB 来存储, 可以支持海量用户的操作频率限制, 而且代码非常简洁高效.
    Continue reading »

    Posted by ideawu at 2015-03-10 17:49:02
|<<<123456789>>>| 1/9 Pages, 54 Results.