实现方法
function
关键字引入了一个方法。 方法实现PHP中常用的可见性修饰符。 在 Zephir中, 必须明确设置可见性修改器:
namespace Test;
class MyClass
{
public function myPublicMethod()
{
// ...
}
protected function myProtectedMethod()
{
// ...
}
private function myPrivateMethod()
{
// ...
}
}
方法可以接收所需的和可选的参数:
namespace Test;
class MyClass
{
/**
* All parameters are required
*/
public function doSum1(a, b)
{
return a + b;
}
/**
* Only 'a' is required, 'b' is optional and it has a default value
*/
public function doSum2(a, b = 3)
{
return a + b;
}
/**
* Both parameters are optional
*/
public function doSum3(a = 1, b = 2)
{
return a + b;
}
/**
* Parameters are required and their values must be integer
*/
public function doSum4(int a, int b)
{
return a + b;
}
/**
* Static typed with default values
*/
public function doSum4(int a = 4, int b = 2)
{
return a + b;
}
}
可选参数可以为空
Zephir确保变量的值保持声明的类型不变。 这使得Zephir将 null
值转换为最近的近似值:
public function foo(int a = null)
{
echo a; // if "a" is not passed it prints 0
}
public function foo(boolean a = null)
{
echo a; // if "a" is not passed it prints false
}
public function foo(string a = null)
{
echo a; // if "a" is not passed it prints an empty string
}
public function foo(array a = null)
{
var_dump(a); // if "a" is not passed it prints an empty array
}
支持可见性
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,而无需显式地实现这些方法。
例如,如果没有快捷方式,我们需要如下代码:
namespace Test;
class MyClass
{
protected myProperty;
protected someProperty = 10;
public function setMyProperty(myProperty)
{
let this->myProperty = myProperty;
}
public function getMyProperty()
{
return this->myProperty;
}
public function setSomeProperty(someProperty)
{
let this->someProperty = someProperty;
}
public function getSomeProperty()
{
return this->someProperty;
}
public function __toString()
{
return this->myProperty;
}
}
您可以使用以下快捷方式编写相同的代码:
namespace App;
class MyClass
{
protected myProperty {
set, get, toString
};
protected someProperty = 10 {
set, get
};
}
在编译代码时,这些方法作为实际方法导出,但您不必手动编写它们。
返回类型提示
类和接口中的方法可以有“返回类型提示”。 这些将为编译器提供有用的额外信息,以告知您应用程序中的错误。 请考虑下面的示例:
namespace App;
class MyClass
{
public function getSomeData() -> string
{
// 这会引发编译器异常
// 因为返回的值(布尔值)不匹配
// 预期返回的类型字符串
return false;
}
public function getSomeOther() -> <App\MyInterface>
{
// 这会引发编译器异常
// 如果返回的对象没有实现
// 期望的接口App\MyInterface
return new App\MyObject;
}
public function process()
{
var myObject;
// 类型提示会告诉编译器这一点
// myObject是一个类的实例
// 实现应用程序\MyInterface
let myObject = this->getSomeOther();
// 编译器会检查App\MyInterface是否正确
// 实现一个名为“someMethod”的方法
echo myObject->someMethod();
}
}
一个方法可以有多个返回类型。 在定义多个类型时,必须使用操作符 |
来分隔这些类型。
namespace App;
class MyClass
{
public function getSomeData(a) -> string | bool
{
if a == false {
return false;
}
return "error";
}
}
返回类型: Void
方法也可以标记为 void
。 这意味着不允许方法返回任何数据:
public function setConnection(connection) -> void
{
let this->_connection = connection;
}
为什么这是有用的? 因为编译器可以检测程序是否期望从这些方法返回值,并产生一个编译器异常:
let myDb = db->setConnection(connection); // 这将产生一个异常
myDb->execute("SELECT * FROM robots");
严格/灵活的参数的数据类型
在 Zephir中, 可以指定方法的每个参数的数据类型。 默认情况下, 这些数据类型是灵活的。这意味着, 如果传递了具有错误 (但兼容) 数据类型的值, 则 Zephir 将尝试以透明方式将其转换为预期的数据类型:
public function filterText(string text, boolean escape=false)
{
//...
}
上述方法将适用于以下调用:
<?php
$o->filterText(1111, 1); // OK
$o->filterText("some text", null); // OK
$o->filterText(null, true); // OK
$o->filterText("some text", true); // OK
$o->filterText(array(1, 2, 3), true); // FAIL
但是, 传递错误的类型通常会导致错误。 不正确地使用特定的 api 会产生意外的结果。 通过使用严格的数据类型设置参数, 可以禁止自动转换:
public function filterText(string! text, boolean escape=false)
{
//...
}
现在,由于传递的数据类型无效,大多数类型错误的调用都会导致异常:
<?php
$o->filterText(1111, 1); // FAIL
$o->filterText("some text", null); // OK
$o->filterText(null, true); // FAIL
$o->filterText("some text", true); // OK
$o->filterText(array(1, 2, 3), true); // FAIL
通过指定严格的参数和灵活的参数,开发人员可以设置他/她真正想要的特定行为。
只读参数
使用关键字const
,您可以将参数标记为只读,这有助于尊重const-correctness。 属性中不能修改标有此属性的参数 方法:
namespace App;
class MyClass
{
// "a" is read-only
public function getSomeData(const string a)
{
// this will throw a compiler exception
let a = "hello";
}
}
当一个参数被声明为只读时,编译器可以做出安全的假设,并对这些变量进行进一步的优化。