• 实现方法
    • 可选参数可以为空
    • 支持可见性
    • 支持修改器
    • Getter / Setter 快捷方式
    • 返回类型提示
    • 返回类型: Void
    • 严格/灵活的参数的数据类型
    • 只读参数

    实现方法

    function关键字引入了一个方法。 方法实现PHP中常用的可见性修饰符。 在 Zephir中, 必须明确设置可见性修改器:

    1. namespace Test;
    2. class MyClass
    3. {
    4. public function myPublicMethod()
    5. {
    6. // ...
    7. }
    8. protected function myProtectedMethod()
    9. {
    10. // ...
    11. }
    12. private function myPrivateMethod()
    13. {
    14. // ...
    15. }
    16. }

    方法可以接收所需的和可选的参数:

    1. namespace Test;
    2. class MyClass
    3. {
    4. /**
    5. * All parameters are required
    6. */
    7. public function doSum1(a, b)
    8. {
    9. return a + b;
    10. }
    11. /**
    12. * Only 'a' is required, 'b' is optional and it has a default value
    13. */
    14. public function doSum2(a, b = 3)
    15. {
    16. return a + b;
    17. }
    18. /**
    19. * Both parameters are optional
    20. */
    21. public function doSum3(a = 1, b = 2)
    22. {
    23. return a + b;
    24. }
    25. /**
    26. * Parameters are required and their values must be integer
    27. */
    28. public function doSum4(int a, int b)
    29. {
    30. return a + b;
    31. }
    32. /**
    33. * Static typed with default values
    34. */
    35. public function doSum4(int a = 4, int b = 2)
    36. {
    37. return a + b;
    38. }
    39. }

    可选参数可以为空

    Zephir确保变量的值保持声明的类型不变。 这使得Zephir将 null值转换为最近的近似值:

    1. public function foo(int a = null)
    2. {
    3. echo a; // if "a" is not passed it prints 0
    4. }
    5. public function foo(boolean a = null)
    6. {
    7. echo a; // if "a" is not passed it prints false
    8. }
    9. public function foo(string a = null)
    10. {
    11. echo a; // if "a" is not passed it prints an empty string
    12. }
    13. public function foo(array a = null)
    14. {
    15. var_dump(a); // if "a" is not passed it prints an empty array
    16. }

    支持可见性

    • Public: 将标记为 public的方法导出到PHP扩展; 这意味着公共方法对PHP代码和扩展本身都是可见的。

    • Protected: 将标记为protected的方法导出到PHP扩展; 这意味着受保护的方法对PHP代码和扩展本身都是可见的。 但是,受保护的方法只能在类的作用域中调用,或者在继承它们的类中调用。

    • Private: 标记为 private 的方法不会导出到PHP扩展; 这意味着私有方法只对实现它们的类可见。

    支持修改器

    • static: 使用此修饰符的方法只能在静态上下文(来自类,而不是对象) 中调用。

    • final: 如果方法具有此修饰符, 则无法对其进行覆盖.

    • deprecated: 被标记为deprecated的方法在被调用时抛出一个E_DEPRECATED错误。

    Getter / Setter 快捷方式

    和C#一样,在Zephir中可以使用get/set/toString快捷方式。 该特性允许您轻松编写属性的setter和getter,而无需显式地实现这些方法。

    例如,如果没有快捷方式,我们需要如下代码:

    1. namespace Test;
    2. class MyClass
    3. {
    4. protected myProperty;
    5. protected someProperty = 10;
    6. public function setMyProperty(myProperty)
    7. {
    8. let this->myProperty = myProperty;
    9. }
    10. public function getMyProperty()
    11. {
    12. return this->myProperty;
    13. }
    14. public function setSomeProperty(someProperty)
    15. {
    16. let this->someProperty = someProperty;
    17. }
    18. public function getSomeProperty()
    19. {
    20. return this->someProperty;
    21. }
    22. public function __toString()
    23. {
    24. return this->myProperty;
    25. }
    26. }

    您可以使用以下快捷方式编写相同的代码:

    1. namespace App;
    2. class MyClass
    3. {
    4. protected myProperty {
    5. set, get, toString
    6. };
    7. protected someProperty = 10 {
    8. set, get
    9. };
    10. }

    在编译代码时,这些方法作为实际方法导出,但您不必手动编写它们。

    返回类型提示

    类和接口中的方法可以有“返回类型提示”。 这些将为编译器提供有用的额外信息,以告知您应用程序中的错误。 请考虑下面的示例:

    1. namespace App;
    2. class MyClass
    3. {
    4. public function getSomeData() -> string
    5. {
    6. // 这会引发编译器异常
    7. // 因为返回的值(布尔值)不匹配
    8. // 预期返回的类型字符串
    9. return false;
    10. }
    11. public function getSomeOther() -> <App\MyInterface>
    12. {
    13. // 这会引发编译器异常
    14. // 如果返回的对象没有实现
    15. // 期望的接口App\MyInterface
    16. return new App\MyObject;
    17. }
    18. public function process()
    19. {
    20. var myObject;
    21. // 类型提示会告诉编译器这一点
    22. // myObject是一个类的实例
    23. // 实现应用程序\MyInterface
    24. let myObject = this->getSomeOther();
    25. // 编译器会检查App\MyInterface是否正确
    26. // 实现一个名为“someMethod”的方法
    27. echo myObject->someMethod();
    28. }
    29. }

    一个方法可以有多个返回类型。 在定义多个类型时,必须使用操作符 |来分隔这些类型。

    1. namespace App;
    2. class MyClass
    3. {
    4. public function getSomeData(a) -> string | bool
    5. {
    6. if a == false {
    7. return false;
    8. }
    9. return "error";
    10. }
    11. }

    返回类型: Void

    方法也可以标记为 void。 这意味着不允许方法返回任何数据:

    1. public function setConnection(connection) -> void
    2. {
    3. let this->_connection = connection;
    4. }

    为什么这是有用的? 因为编译器可以检测程序是否期望从这些方法返回值,并产生一个编译器异常:

    1. let myDb = db->setConnection(connection); // 这将产生一个异常
    2. myDb->execute("SELECT * FROM robots");

    严格/灵活的参数的数据类型

    在 Zephir中, 可以指定方法的每个参数的数据类型。 默认情况下, 这些数据类型是灵活的。这意味着, 如果传递了具有错误 (但兼容) 数据类型的值, 则 Zephir 将尝试以透明方式将其转换为预期的数据类型:

    1. public function filterText(string text, boolean escape=false)
    2. {
    3. //...
    4. }

    上述方法将适用于以下调用:

    1. <?php
    2. $o->filterText(1111, 1); // OK
    3. $o->filterText("some text", null); // OK
    4. $o->filterText(null, true); // OK
    5. $o->filterText("some text", true); // OK
    6. $o->filterText(array(1, 2, 3), true); // FAIL

    但是, 传递错误的类型通常会导致错误。 不正确地使用特定的 api 会产生意外的结果。 通过使用严格的数据类型设置参数, 可以禁止自动转换:

    1. public function filterText(string! text, boolean escape=false)
    2. {
    3. //...
    4. }

    现在,由于传递的数据类型无效,大多数类型错误的调用都会导致异常:

    1. <?php
    2. $o->filterText(1111, 1); // FAIL
    3. $o->filterText("some text", null); // OK
    4. $o->filterText(null, true); // FAIL
    5. $o->filterText("some text", true); // OK
    6. $o->filterText(array(1, 2, 3), true); // FAIL

    通过指定严格的参数和灵活的参数,开发人员可以设置他/她真正想要的特定行为。

    只读参数

    使用关键字const,您可以将参数标记为只读,这有助于尊重const-correctness。 属性中不能修改标有此属性的参数 方法:

    1. namespace App;
    2. class MyClass
    3. {
    4. // "a" is read-only
    5. public function getSomeData(const string a)
    6. {
    7. // this will throw a compiler exception
    8. let a = "hello";
    9. }
    10. }

    当一个参数被声明为只读时,编译器可以做出安全的假设,并对这些变量进行进一步的优化。