dongxu198714 2013-03-10 03:02
浏览 43
已采纳

PHP:从全局函数访问封闭的范围

I'm scratching my head at some PHP code. I can't tell if it logically works yet, as I'm quite new to PHP and it won't execute yet due to a syntax error: syntax error, unexpected 'use' (T_USE), expecting '{'

The syntax error is tripping up on a use, despite the PHP version fully supporting it, and the syntax (as far as I can tell) being correct.

The code checks which database implementation is specified, and it'll define the functions for whichever one it is. Because I can't define functions returned from other functions as global functions, I store it in them in variables, 'wrapping' access via global functions that capture the variables from their outer scopes, or at least they should do.

The two lines yielding errors have been marked:-

function query_escaper($element_escaper) {
    return function($query, $values) use ($element_escaper) {
        return join(array_map(
            function($query_elem, $value) {
                return isset($value)
                    ? $query_elem . $element_escaper($value)
                    : $query_elem
                    ;
            },
            explode('?', $query),
            $values
        ));
    };
}

function define_postgresql_functions() {

    [...]

    $escape_query = query_escaper('pg_escape_literal');

    #
    # XXX The error occurs here :-
    #
    function escape_query() use ($escape_query) {
        return call_user_func_array($escape_query, func_get_args());
    }

    [...]
}

function define_mysql_functions() {

    [...]

    $escape_query = query_escaper(function($str) {
        return use_database(function($database) use ($str) {
            return $database->real_escape_string($str);
        });
    });

    #
    # XXX The same error also occurs here :-
    #
    function escape_query() use ($escape_query) {
        return call_user_func_array($escape_query, func_get_args());
    }

    [...]
}

switch ($database_info['type']) {
case 'postgresql':
    define_postgresql_functions();
    break;
case 'mysql':
    define_mysql_functions();
    break;
default:
    throw new DatabaseNotImplementedException();
}

I'm looking for two possible solutions: either being able to capture those variables from the outer scope, or another way of defining global functions as functions returned from other functions.

  • 写回答

1条回答 默认 最新

  • duanlun4411 2013-03-10 03:12
    关注

    The pattern function\s+\w+ always declares a function in the global scope, meaning you have to use the global syntax. This means you can't name the function if you're creating a closure. So this is invalid:

    function escape_query()  use ($escape_query) {
    

    But this would work fine:

    $escape_function = function() use ($escape_query) {
    

    There are a few different ways to accomplish what you want. eval comes to mind, as does using a static variable in the function, or the OOP solution.

    I think the OOP solution is probably the easiest:

    class Escaper {
    
        public static $escape_function;
    }
    
    
    // in your function
    Escaper::$escape_function = function() use ($escape_query) { //...
    
    // later
    Escaper::$escape_function('a','b','c');
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 BP神经网络控制倒立摆
  • ¥20 要这个数学建模编程的代码 并且能完整允许出来结果 完整的过程和数据的结果
  • ¥15 html5+css和javascript有人可以帮吗?图片要怎么插入代码里面啊
  • ¥30 Unity接入微信SDK 无法开启摄像头
  • ¥20 有偿 写代码 要用特定的软件anaconda 里的jvpyter 用python3写
  • ¥20 cad图纸,chx-3六轴码垛机器人
  • ¥15 移动摄像头专网需要解vlan
  • ¥20 access多表提取相同字段数据并合并
  • ¥20 基于MSP430f5529的MPU6050驱动,求出欧拉角
  • ¥20 Java-Oj-桌布的计算