Scholer

Scholer 查看完整档案

武汉编辑  |  填写毕业院校  |  填写所在公司/组织 0x1.im 编辑
编辑

305611088 PHP交流群。希望PHP的交流活跃起来,质量高起来。

个人动态

Scholer 赞了文章 · 7月7日

PHP常用函数前100排行榜

一、背景

这两天在努力记单词,想着应该把最常使用的单词先记下来,从网上找了几篇文章之后分析了一批词汇,效果还算不错;

接着又想到了代码,也好奇开发者最常使用的单词或函数有哪些,我统计了三种类型:系统函数、变量名、自定义函数名等统计,感兴趣的朋友可以将正则设置为自己需要统计的规则。

二、参考代码

<?php

function scanMyDir($path)
{
    $path = rtrim($path, '/');
    // 打开目录
    $dh = opendir($path);

    // 循环读取目录
    while (($file = readdir($dh)) !== false) {
        // 先要过滤掉当前目录'.'和上一级目录'..'
        if ($file == '.' || $file == '..' || $file == '.git') continue;

        if (strpos($file, ".php") > 1) {
            // 为了能够显示中文目录/文件,需要进行转码
            $_SERVER['fileList'][] = $path . '/' . iconv('gbk', 'utf-8', $file);
        }

        // 如果该文件仍然是一个目录,进入递归
        if (is_dir($path . '/' . $file)) {
            scanMyDir($path . '/' . $file);
        }
    }
}


function explodeCount($fileName, $pregRule)
{
    $text = file_get_contents($fileName);
    preg_match_all($pregRule, $text, $keywordArr);
    foreach ($keywordArr[1] as $keyword) {
        $_SERVER['count'][$keyword] = $_SERVER['count'][$keyword] ?? 0;
        $_SERVER['count'][$keyword] += 1;
    }
}

function start($path, $pregRule)
{
    scanMyDir($path);
    //把要统计的文件写入到当前文件夹中,方便查看统计了那些文件
    file_put_contents("fileList.txt", implode("\n", $_SERVER['fileList']));

    //从上一个文件中读取要统计的文件列表,
    $fileList = file_get_contents("fileList.txt");
    $fileList = explode("\n", $fileList);

    //遍历统计每个文件中的词汇
    foreach ($fileList as $fileName) {
        explodeCount($fileName, $pregRule);
    }

    //将结果写入到文件当中之前,先做好排序
    arsort($_SERVER['count']);
    //只需要前100个
    $_SERVER['count'] = array_slice($_SERVER['count'], 0, 100);
    //将结果写入到文件中去
    $sumResult = var_export($_SERVER['count'], true);
    file_put_contents("countResult.txt", $sumResult);
}


//要统计的代码目录
$path = '/root/mycode/work/offcn-live/vendor';

//$pregRule = '/ ([a-z]+_?[a-z]+)\(/';  //系统函数规则
//$pregRule = '/(\$[a-zA-Z]+_?[a-zA-Z]+)/';   //变量名规则
$pregRule = '/[->:]+([a-z]+_?[a-z]+)\(/'; //自定义函数名规则
start($path, $pregRule);

三、常用函数

array (
  'array' => 6126,
  'isset' => 1345,
  'substr' => 845,
  'sprintf' => 737,
  'strlen' => 650,
  'count' => 598,
  'unset' => 556,
  'array_merge' => 449,
  'list' => 413,
  'strpos' => 408,
  'str_replace' => 393,
  'implode' => 348,
  'explode' => 333,
  'is_array' => 332,
  'static' => 297,
  'trim' => 263,
  'declare' => 238,
  'mock' => 237,
  'pack' => 232,
  'preg_match' => 222,
  'is_null' => 210,
  'get_class' => 203,
  'array_map' => 195,
  'self' => 191,
  'strtolower' => 190,
  'empty' => 183,
  'preg_replace' => 180,
  'chr' => 169,
  'function_exists' => 163,
  'user_error' => 161,
  'handle' => 158,
  'is_string' => 155,
  'is_object' => 140,
  'str_repeat' => 139,
  'array_keys' => 138,
  'rewind' => 137,
  'in_array' => 133,
  'write' => 132,
  'mt_rand' => 132,
  'array_values' => 129,
  'time' => 125,
  'not' => 124,
  'array_shift' => 124,
  'extract' => 120,
  'getenv' => 115,
  'reset' => 113,
  'execute' => 112,
  'printf' => 110,
  'fopen' => 108,
  'get' => 105,
  'collect' => 100,
  'current' => 100,
  'fclose' => 99,
  'unpack' => 96,
  'strval' => 96,
  'matches' => 92,
  'rtrim' => 90,
  'str_pad' => 88,
  'json_encode' => 88,
  'array_filter' => 88,
  'array_pop' => 85,
  'app' => 84,
  'range' => 84,
  'dirname' => 83,
  'define' => 81,
  'microtime' => 80,
  'foo' => 80,
  'create' => 80,
  'ord' => 80,
  'compact' => 79,
  'read' => 77,
  'method_exists' => 76,
  'register' => 75,
  'realpath' => 74,
  'intval' => 73,
  'bar' => 73,
  'strtotime' => 73,
  'fread' => 72,
  'class_exists' => 72,
  'print' => 72,
  'max' => 72,
  'curl_setopt' => 70,
  'fwrite' => 69,
  'tap' => 66,
  'strtoupper' => 65,
  'array_unshift' => 65,
  'serialize' => 64,
  'ob_start' => 64,
  'unserialize' => 63,
  'strrpos' => 61,
  'key' => 61,
  'preg_split' => 61,
  'ini_get' => 61,
  'add' => 59,
  'close' => 59,
  'array_slice' => 58,
  'putenv' => 57,
  'eval' => 57,
  'gettype' => 56,
  'var_export' => 56,
)

四、常用变量名

array (
  '$this' => 75572,
  '$value' => 6303,
  '$options' => 4731,
  '$key' => 4597,
  '$name' => 4367,
  '$vendorDir' => 4310,
  '$message' => 4115,
  '$request' => 3453,
  '$stackPos' => 3237,
  '$response' => 2796,
  '$result' => 2577,
  '$data' => 2308,
  '$path' => 2117,
  '$node' => 1733,
  '$type' => 1650,
  '$method' => 1620,
  '$file' => 1449,
  '$arguments' => 1415,
  '$class' => 1408,
  '$callback' => 1378,
  '$output' => 1364,
  '$command' => 1314,
  '$parameters' => 1273,
  '$config' => 1252,
  '$expected' => 1197,
  '$column' => 1153,
  '$input' => 1140,
  '$id' => 1119,
  '$headers' => 1083,
  '$event' => 1083,
  '$args' => 986,
  '$attributes' => 979,
  '$length' => 961,
  '$code' => 950,
  '$query' => 947,
  '$prefix' => 947,
  '$mock' => 930,
  '$token' => 925,
  '$context' => 909,
  '$test' => 892,
  '$temp' => 884,
  '$header' => 871,
  '$matches' => 847,
  '$object' => 825,
  '$string' => 813,
  '$container' => 810,
  '$server' => 810,
  '$stream' => 768,
  '$collection' => 768,
  '$route' => 761,
  '$values' => 761,
  '$record' => 748,
  '$exception' => 748,
  '$actual' => 719,
  '$connection' => 712,
  '$item' => 697,
  '$constraint' => 670,
  '$operation' => 666,
  '$date' => 655,
  '$bucket' => 648,
  '$array' => 644,
  '$line' => 643,
  '$count' => 641,
  '$uri' => 622,
  '$buf' => 618,
  '$handler' => 608,
  '$default' => 598,
  '$table' => 594,
  '$content' => 578,
  '$reader' => 558,
  '$resource' => 549,
  '$application' => 549,
  '$tokens' => 541,
  '$locale' => 539,
  '$attribute' => 531,
  '$format' => 518,
  '$filename' => 510,
  '$className' => 509,
  '$str' => 505,
  '$parts' => 505,
  '$matcher' => 499,
  '$text' => 498,
  '$queue' => 483,
  '$generator' => 480,
  '$filter' => 476,
  '$client' => 475,
  '$level' => 468,
  '$domain' => 467,
  '$writer' => 464,
  '$argument' => 460,
  '$number' => 459,
  '$option' => 452,
  '$payload' => 448,
  '$keys' => 445,
  '$process' => 444,
  '$translator' => 437,
  '$app' => 435,
  '$listener' => 430,
  '$files' => 429,
  '$index' => 422,
)

五、常用自定义函数

array (
  'once' => 1292,
  'with' => 1105,
  'get' => 997,
  'expects' => 700,
  'method' => 651,
  'set' => 612,
  'create' => 600,
  'add' => 588,
  'foo' => 464,
  'format' => 434,
  'write' => 429,
  'execute' => 421,
  'all' => 378,
  'evaluate' => 344,
  'has' => 320,
  'register' => 318,
  'fail' => 294,
  'find' => 286,
  'run' => 284,
  'any' => 280,
  'start' => 254,
  'parse' => 233,
  'load' => 203,
  'make' => 200,
  'read' => 191,
  'generate' => 185,
  'factory' => 182,
  'close' => 164,
  'current' => 155,
  'render' => 152,
  'ask' => 149,
  'numerify' => 146,
  'will' => 145,
  'where' => 137,
  'singleton' => 133,
  'writeln' => 128,
  'valid' => 125,
  'next' => 124,
  'main' => 122,
  'send' => 121,
  'trans' => 117,
  'request' => 116,
  'option' => 113,
  'handle' => 112,
  'matches' => 111,
  'match' => 110,
  'contains' => 103,
  'write_shortstr' => 103,
  'process' => 101,
  'never' => 100,
  'at' => 99,
  'initialize' => 97,
  'rewind' => 96,
  'bind' => 92,
  'validate' => 90,
  'dispatch' => 88,
  'filter' => 86,
  'in' => 86,
  'copy' => 85,
  'verify' => 84,
  'delete' => 83,
  'wrap' => 81,
  'put' => 79,
  'stop' => 78,
  'mock' => 78,
  'dump' => 78,
  'supports' => 78,
  'observe' => 77,
  'encrypt' => 77,
  'attach' => 75,
  'first' => 74,
  'apply' => 73,
  'remove' => 72,
  'invoke' => 72,
  'connection' => 71,
  'advance' => 69,
  'decrypt' => 69,
  'ordered' => 69,
  'save' => 68,
  'resolve' => 68,
  'prepare' => 67,
  'println' => 67,
  'auth' => 65,
  'reset' => 65,
  'bar' => 64,
  'write_short' => 64,
  'call' => 63,
  'map' => 63,
  'compare' => 63,
  'string' => 62,
  'log' => 62,
  'wait' => 61,
  'info' => 61,
  'update' => 60,
  'escape' => 60,
  'lookup' => 58,
  'write_bits' => 57,
  'count' => 57,
  'push' => 56,
  'times' => 55,
)

后面的数字,代表为在代码中出现的次数,我用的四项目的vendor目录,里面都是一些比较常用的开源代码库,所以应该算是比较有参考价值

作者:汤青松
日期: 2020-06-30

查看原文

赞 23 收藏 16 评论 2

Scholer 发布了文章 · 7月7日

使用 Golang 实现一个 JSON 命令行工具

首先先提一个问题,"abc"123 或者 [1, 2, 3] 是不是一个合法的 json ?

之前一直有在使用一个 json 的命令行工具 jq,这个工具是基于 flex 和 bison 来实现的(去了解这些是基于当年学习 php 的经历)。后来有段时间我又发现一个不错的词法和语法分析工具 antlr,它支持多种语言的生成,并且本身也提供了多种语言的基本语法文件。所以我就想能不用基于它实现一个 go 语言版的 json 命令行工具。

下面就开始一步一步行动吧(如果想直接看代码可以直接拉到底部),我将这个项目命名为 jtlr

提供的功能

根据我自己常使用的场景,我要实现以下几个功能:

基本用法:

jtlr '{"a": 1}'

交互模式,可以多次输入,并且最好能支持上下切换:

jtlr -a

从标准输入中读取内容,可以格式化实时输出的日志:

tail -f xxx.log | jtlr -s

从文件中读取:

jtlr -f xxx.log

什么是 json

在动手之前,先要对 json 有一个全面的认识。先来大致看一下官网提供的 json 的 BNF 范式的起始部分:

json
    element

value
    object
    array
    string
    number
    "true"
    "false"
    "null"

...

element
    ws value ws

ws 是 whitespace 的缩写,即空白字符,忽略这个之后,即可简单清晰的看到 json 的内的有效数值。虽然我们常用的 json 内容都是 object 起的,但并不是一定要从 object 开始,所以对于文章开头那个问题,你有答案了吗?

在实现时我并没有去复制官网提供的 BNF,而是采用了 antlr4 提供的语法,关于它的实现,这里有一篇文章说明:https://andreabergia.com/a-grammar-for-json-with-antlr-v4/

简单来说,json 有七种的数据,其中 arrayobject 是可以再包含 value,剩下五种就是基本的数值数据。

此外,还有一类比较特殊的情况,就是对 string 的用法:

member
    ws string ws ':' element

string 既可以是一个基本类型的 value,也可以一个对象成员的键值。这会导致我们在对 string 做上色等处理时需要考虑着两种情况。

antlr4 提供的接口

使用下面的命令即可生成基于 go 语言的 lexer 和 parser:

antlr -Dlanguage=Go -o parser/ JSON.g4

接下来就是功能实现的工作了。

antlr4 生成的接口比较完备,包含每个分支逻辑进入、退出和错误节点访问的接口。并且有较好的错误纠正和提示机制。

但对于 json 本身这个 case,需要注意的是对 valuestring。上面也有提到,所有七类数值都是 value,所以都会触发 EnterValueExitValue 事件,string 同理。

对于 objectarray 来说,比较棘手的在于嵌套的数据,例如:

{"a": [134, {"a": 1}, true, [1, 2, 3], false]}

在使用 antlr4 提供的接口时,需要标注进入和退出的顺序。

交互模式下的问题

最开始我做了个非常简单的交互模式的实现:

reader := bufio.NewReader(os.Stdin)
for {
    fmt.Print(">>> ")
    text, err := reader.ReadString('\n')
    if err == io.EOF {
        break
    }
    if text == "\n" || text == "\r\n" {
        continue
    }
    fn(text)
}

但是在这种实现逻辑下,上下左右等按键会直接打印在屏幕上而无法正确处理,因为终端处于 cooked mode 下。go 本身也没有提供 tty 的封装。所以要进入 raw mode,一种是通过直接 call 起命令行的方式:

func raw(start bool) error {
    r := "raw"
    if !start {
        r = "-raw"
    }

    rawMode := exec.Command("stty", r)
    rawMode.Stdin = os.Stdin
    err := rawMode.Run()
    if err != nil {
        return err
    }

    return rawMode.Wait()
}

另外一种是操作 stdin 的文件句柄,这样实现起来就相当复杂了。

出于兼容性和可维护性的考虑,我使用了 golang/crypto 提供的 terminal 的封装,这也是项目中除了 antlr 以外唯一一个引入的第三方包(如果算是第三方的话)。

但是这个包有一个问题是必须使用 \r\n 进行回车(官方的 issue 解释是一些历史原因吧啦吧啦),不然光标不会回到行首,但是 go 标准的 fmt 包中使用的 \n 换行,而 antlr 使用了 fmt 进行错误输出,所以需要对错误输出进行重载。

未完成

从开始构思到实现到当前阶段,大概耗时两个周末了。

由于前期偷懒,格式化输出全部使用的是 fmt,这里后续需要优化一下。

现在的实现对于 antlr 来说有点像用牛刀杀鸡,jq 本身支持的节点选取,这是后续实现的一个方向。

另外,go 官方虽然提供了官方的 json 序列化和反序列化工具,但是市面上也有一些第三方的实现被使用,我也想探讨一下实现方式。

另外,windows 下还没做完全的兼容测试。

最后,贴上项目地址:https://github.com/XiaoLer/jtlr-go

查看原文

赞 2 收藏 1 评论 0

Scholer 发布了文章 · 2017-01-08

如何学习 PHP 源码 - 从编译开始

PHP Mailing Lists 上这两天有个好玩儿的问题:Introduction to the PHP source code,大概就是有人想知道如何学习 PHP 源码,可是这种事情不是应该自己去发掘的吗?

上面是玩笑话,现在我也说说如何学习 PHP 解释器的源码。

首选你要知道的是 PHP 解释器源码的 github 地址:https://github.com/php/php-src ,话说回来还有人不知道吗?这里有几乎所有 PHP 的代码提交记录、pull requests 和一些 issue 等。

创建编译脚本或者发布包

从 Branch 中选择一个版本 tag,和每次 PHP 发布出来的版本就是一致的。也许你会发现你想编译的的时候缺找不到 configure 文件,但是有 configure.in 文件。这时候需要先执行的是 buildconf(如果是在 Windows 下面可以执行 buildconf.bat,不过我从来没有尝试过在 Windows 下面编译 PHP,所以具体的步骤我就不清楚了)。buildconf 本身是个简单的 shell 脚本,你可以用记事本打开看看它(最终的执行文件在 build 目录里,这个目录里有一些与编译有关的文件)。

这里面涉及到一个系列的编译工具:Autotools。如果你有兴趣,可以简单的了解一下,没有兴趣的话也不用多考虑,因为这些工具绝大多数 Linux 系统上都是已经存在的。

如果你想将 Github 上的 PHP 源码做成一个可发布的源码包,你可以看看 makedist 这个文件,它也是一个 shell 脚本(实际上源码里几乎所有跟编译相关的脚本都是 shell 脚本)。但是如果想直接执行者这个脚本,你可能会收到缺少以下组件的提示:re2cBison。仔细看 makedist 的文件,里面有调用 genfiles 这个脚本的语句,上面两个工具就是在 genfiles 的脚本里被调用的。

re2c 和 Bison 分别是 PHP 用到的词法解析器和语法分析器。在 genfiles 这个文件中可以看到它们的调用其实是在 Makefile.frag 中写着,分别通过 zend_language_scanner.lzend_language_parser.y 生成相应的 C 语言文件(这个应该很多地方都有提到过)。

编译解释器并初始化

到了编译环节,编译之前需要先通过 configure 文件生成 Makefile 然后执行 make,所以 gcc 自然是必不可少的。configure 文件本身也是一个 shell 脚本,你也可以简单阅读一下它的内容。不过既然它是由 autoconfconfigure.in 中生成的,也许直接查看 configure.in 会更轻松一些。

到这里总结一下就是:抛开一些核心扩展额依赖(比如 xml,ssl 等),编译 PHP 的先决条件是机器上有 Autotools 的工具(automake,autoconf 等),需要安装 re2c 和 Bison,当然还有编译工具(gcc)。

也许大家都知道,使用 configure 生成 Makefile 的时候可以通过 --prefix 参数指定目录,同时也可以选择编译哪些核心模块。至于哪些模块会被默认集成而哪些不会,这些本身是写在每个扩展的 config.m4 (也有几个是被命名为 config0.m4 或 config9.m4)文件里的的,全都通过一些 --enable--disable--with--without 的选项来控制。

编译的也与你采用的 Web 服务器有关,这涉及到你需要使用哪个 sapi,如果是 Apache,也许需要指定 --with-apxs2 的参数,如果是 Nginx,php-fpm 在默认条件下是会被编译的,但可以指定 php-fpm 的执行组和用户,不过这个是可以在编译完成后在配置中修改的。

编译完成之后还有一些事情需要考虑,最基本的问题是 PHP 的配置文件的问题,还有一个是如果使用的是 php-fpm,如何更便捷的控制它的启动、停止以及重启等。

在 PHP 源码根中已经准备了两份配置文件的模板:php.ini-developmentphp.ini-production。显然是分别用于开发环境和生产环境的,将其中一个复制到配置文件目录并重命名为 php.ini 即可(如果你不知道配置文件的目录在哪里,可以使用 php --ini 命令查看)。然后也可以根据你的需要修改它。

至于 php-fpm 的控制脚本,源码中本身也是有提供的,在 sapi/fpm 目录下。这个目录下的几个文件中有 php-fpm 配置文件的模板,也有稍微修改即可放到服务器 /etc/init.d 目录下用于控制 php-fpm 的 startstoprestartreload 动作的脚本,现在的版本中也提供了用于 systemd 的 service 文件。

扩展编译

如果 PHP 编译完成之后,发现还需要一些没有编译进去的核心扩展或者第三方扩展,你可以单独编译它们。

扩展编译的整个过程一共四句命令:

  1. phpize

  2. ./configure

  3. make

  4. make install

phpize 命令是用来准备 PHP 扩展库的编译环境的。在执行 phpize 的时候,如果有多个版本的 PHP,用哪个就要选哪个。这个命令和编译后的 php 的二进制文件在同一个目录中,也是一个 shell 脚本。

执行 configure 的时候,如果当前 $PATH 中找不到 php-config 或者有多个版本的 PHP 时,也需要通过 --with-php-config 的指令来指定 php-config 的目录。php-config 是一个用于获取所安装的 PHP 配置的信息,它也一样是和 php 的二进制文件在同一个目录的 shell 脚本。

phpize 和 php-config 的源码生成文件都是在 scripts 目录下。

所有工作完成之后,就可以愉快的使用你自己定制的 PHP 了。

原文地址:http://0x1.im

查看原文

赞 6 收藏 24 评论 0

Scholer 发布了文章 · 2016-12-22

一个神奇的操作符即将加入PHP

我在翻看 PHP 的 RFC 列表的时候发现了一篇不算新的,但很有意思的 rfc:空合并赋值操作符 (姑且就这么翻译吧)。

它会引起我的注意的还有一个原因是我之前写过这样一篇文章:两行代码给 PHP7 添加一个“非空合并”语法糖,里面讲的是添加一个 ??: 操作符的方法, 而现在要讲的这个,已经被接受的 rfc 里添加的操作符是: ??=

由于这个事情本身可说的不多,这里就根据 rfc 简单描述一下吧。以下部分是 rfc 的翻译。


合并赋值操作符在上世纪七十年代就出现了,最早是在 C 语言里,比如 $x = $x + 3 可以被简写为 $x += 3。随着 PHP 成为一门专注于 Web 的语言,?? 操作符经常会被用去检查变量是否存在:比如:

$username = $_GET['user'] ?? 'nobody';

但是由于大部分情况下变量的名称回避 $username 长很多,所以在使用 ?? 检查后讲变量本身赋值给自己的时候会需要些一些重复的代码,形如以下形式:

 $this->request->data['comments']['user_id'] = $this->request->data['comments']['user_id'] ?? ‘value’;

这就是为什么需要一个能在自我赋值的时候进行空合并检查的赋值操作符的原因。

虽然 ?? 是一个比较操作符,??= 确实一个赋值操作符号。如果左值为 null,右值会被赋给左值,否则不做任何操作。

// 下面这一行有相同的效果
$this->request->data['comments']['user_id'] = $this->request->data['comments']['user_id'] ?? 'value';
// 使用新操作符替代重复的代码
$this->request->data['comments']['user_id'] ??= 'value';

用简单描述就是:左值为空时复制右值。


从实际的工程经验上来说,这个操作符确实能简化判断。这也不是第一个三个字符组成的操作符(除此之外还有 <<=>>====!==)。

这个操作符并没有出现在 PHP7.1 中,因为 rfc 提出来的时候已经 7.1 已经是 beta3 了,而新特性需要在 beta1 时就冻结,所以在 7.2 中应该就可以用上它了。

既然说到简化重复的代码,??= 都已经来了,??: 还会远吗 ? 。

查看原文

赞 4 收藏 3 评论 2

Scholer 回答了问题 · 2016-12-02

laravel视图{!! !!}和{{ }}的区别?

{{ }} 会对输出内容通过 htmlentities 处理,无法在dom中塞入 img 等标签

关注 5 回答 4

Scholer 关注了问题 · 2016-12-02

laravel视图{!! !!}和{{ }}的区别?

使用了一个第三方验证码类库,其中在试图中是{!! Geetest::render() !!}这样来显示验证码的,想问下和{{ * }}这样子有什么区别?

关注 5 回答 4

Scholer 关注了问题 · 2016-12-01

php 为什么常量可以用数组定义 静态变量却不能

<?php
$GLOBALS['arr'] = array(1=>1,2=>2);
define("ABC",$GLOBALS['arr'][1]); # 这个定义可以

class test{
    static  $a = $GLOBALS['arr'][1]; # 这个初始化有语法错误

}

关注 9 回答 4

Scholer 回答了问题 · 2016-12-01

php 为什么常量可以用数组定义 静态变量却不能

因为 $GLOBALS 是在词法定义上属于 ZEND_AST_GLOBAL

而 static 支持的定义判断是这样的:

zend_bool zend_is_allowed_in_const_expr(zend_ast_kind kind) /* {{{ */
{
    return kind == ZEND_AST_ZVAL || kind == ZEND_AST_BINARY_OP
        || kind == ZEND_AST_GREATER || kind == ZEND_AST_GREATER_EQUAL
        || kind == ZEND_AST_AND || kind == ZEND_AST_OR
        || kind == ZEND_AST_UNARY_OP
        || kind == ZEND_AST_UNARY_PLUS || kind == ZEND_AST_UNARY_MINUS
        || kind == ZEND_AST_CONDITIONAL || kind == ZEND_AST_DIM
        || kind == ZEND_AST_ARRAY || kind == ZEND_AST_ARRAY_ELEM
        || kind == ZEND_AST_CONST || kind == ZEND_AST_CLASS_CONST
        || kind == ZEND_AST_MAGIC_CONST || kind == ZEND_AST_COALESCE;
}

关注 9 回答 4

Scholer 关注了问题 · 2016-11-27

php抛出异常后捕获不到

php抛出异常后捕获不到,这个是微信的一个错误,我调用的第三方类,第三方类抛出异常,我这边捕获不到。
调用别的类方法,此类抛出一个异常,在调用的类里捕获不到。

抛出异常的方法
clipboard.png

捕获异常
clipboard.png

感觉是捕获不到

clipboard.png

我的catch里 不管输出什么都是这个错误,执行不到我的代码,我想抛出异常后 处理一下 我的代码接着执行
因为我这个事一个foreach 当其中一个有错误 下面的循环 就不会被执行了

关注 5 回答 3

Scholer 回答了问题 · 2016-11-27

php抛出异常后捕获不到

Exception 前面加个 \ 试试

关注 5 回答 3

认证与成就

  • 获得 173 次点赞
  • 获得 5 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 5 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2014-06-10
个人主页被 1k 人浏览