在 PHP 中是否有等价的“let”与“var”


Is there an equivalent of "let" vs. "var" in PHP?

我最近开始学习 Swift for iOS 开发。我有脚本语言的背景,尤其是PHP。看到强调使用 let 来定义一个常量,以支持var让编译器优化结果代码,我想知道:PHP 有等价物吗?还是它根本不适用,因为 PHP 不是静态编译的?

我尝试了搜索,但没有找到令人满意的信息。

不,在 PHP 中不能有本地范围的常量。所有 PHP 常量始终是全局可见的。也没有像不可变/可变变量这样的概念。

您可以实现不可变对象成员(PHP:不可变的公共成员字段),但这是另一回事。

实际上语言中有一个const关键字,但文档说:

注意:

与使用 define() 定义常量相反,使用 const 关键字定义的常量必须在顶级范围内声明,因为它们是在编译时定义的。这意味着它们不能在函数、循环、if 语句或 try/catch 块中声明。

(来自 http://php.net/manual/en/language.constants.syntax.php)

具有

动态类型系统的解释型语言可以具有类似于 swift let 语句的东西,所以这不是因为 swift 被编译和 PHP 被解释(例如,有一个 javascript 建议引入该功能:https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Statements/const)

在 PHP 中是否有等价的"let"与"var"?

PHP还没有let作为母语功能(截至当前版本7.1.4 - 04/2017)

但是,一些高性能的扩展,如Phalcon和Ice,支持let,因为zephir-lang的基础用法。所以,有let,但间接;使用上述扩展。

有两种用例:

  • 从超级全局定义变量
  • 在本地 PHP 符号表中定义一个变量,例如

    // set variable $price in PHP
    let name = "price";
    let {name} = 10.2;
    

例如,看看 Ice 路由器的源代码:

namespace Ice'Mvc'Route;
use Ice'Mvc'Route'Parser'ParserInterface;
use Ice'Mvc'Route'DataGenerator'DataGeneratorInterface;
use Ice'Mvc'Route'Parser'Std;
use Ice'Mvc'Route'DataGenerator'GroupCount as Generator;
class Collector
{
    private routeParser { set };
    private dataGenerator { set };
    /**
     * Constructs a route collector.
     *
     * @param RouteParser   $routeParser
     * @param DataGenerator $dataGenerator
     */
    public function __construct(<ParserInterface> routeParser = null, <DataGeneratorInterface> dataGenerator = null)
    {
        if !routeParser {
            let routeParser = new Std();
        }
        if !dataGenerator {
            let dataGenerator = new Generator();
        }
        let this->routeParser = routeParser,
            this->dataGenerator = dataGenerator;
    }
    /**
     * Adds a route to the collection.
     *
     * The syntax used in the $route string depends on the used route parser.
     *
     * @param string|array $httpMethod
     * @param string $route
     * @param mixed  $handler
     */
    public function addRoute(var httpMethod, string route, handler = null)
    {
        var routeDatas, routeData, method;
        let routeDatas = this->routeParser->parse(route);
        if typeof httpMethod == "string" {
            let method = httpMethod,
                httpMethod = [method];
        }
        for method in httpMethod {
            for routeData in routeDatas {
                this->dataGenerator->addRoute(method, routeData, handler);
            }
        }
    }
    /**
     * Returns the collected route data, as provided by the data generator.
     *
     * @return array
     */
    public function getData()
    {
        return this->dataGenerator->getData();
    }
}