zephir-(9)类和对象2

时间:2022-04-29
本文章向大家介绍zephir-(9)类和对象2,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

#zephir-(9)类和对象2#

##前言## 先在这里感谢各位zephir开源技术提供者

zephir全面使用对象编程,这就是为什么拓展的使用方式只能是方法和类,你也将看到,大部分的时间,运行时错误引发异常,而不是致命错误或警告。今天讲一步步讲解zephir类方法变量范围等等的使用,希望大家喜欢.

注:笔者水平有限,说的不正确的地方希望大家多多指正,一同交流技术

附上:

喵了个咪的博客:w-blog.cn

zephir官网地址:http://zephir-lang.com/

github地址:https://github.com/phalcon/zephir

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

在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); // 失败

然而,传递一个错误的类型可能会经常导致错误,不使用特定的API会产生意想不到的效果。您可以通过设置一个严格的数据类型的参数禁止自动转换:

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

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

<?php

$o->filterText(1111, 1); // 失败
$o->filterText("some text", null); // OK
$o->filterText(null, true); // 失败
$o->filterText("some text", true); // OK
$o->filterText(array(1, 2, 3), true); // 失败

通过指定什么参数严格,什么是灵活的,开发人员可以做到真正想要的定制行为。

##只读参数##

使用关键字“const”可以参数标记为只读的,内部参数标注该属性不能修改方法:

namespace App;

class MyClass
{
    // "a" 是一个常量
    public function getSomeData(const string a)
    {
        // 这将抛出一个编译器异常
        let a = "hello";
    }
}

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

##类的属性##

类成员变量被称为“属性”。默认情况下,他们作为PHP的属性。属性实现通常使用可见性修饰符,在Zephir中可见性修饰符是强制性的:

namespace Test;

class MyClass
{

    public myProperty1;

    protected myProperty2;

    private myProperty3;

}

在类方法访问非静态属性可以通过使用->(对象操作符):这个->属性:

namespace Test;

class MyClass
{

    protected myProperty;

    public function setMyProperty(var myProperty)
    {
        let this->myProperty = myProperty;
    }

    public function getMyProperty()
    {
        return this->myProperty;
    }
}

属性可以有默认值。这些值必须能够被定义,编译时,不得依赖于运行时的其他值:

namespace Test;

class MyClass
{

    protected myProperty1 = null;
    protected myProperty2 = false;
    protected myProperty3 = 2.0;
    protected myProperty4 = 5;
    protected myProperty5 = "my value";
}

##更新属性##

开发人员可以通过“->属性”更新属性值:

let this->myProperty = 100;

zephir会检查该属性是否存在,如果一个属性没有声明,你会得到一个编译警告:

CompilerException: Property '_optionsx' is not defined on class 'AppMyClass' in /Users/scott/utils/app/myclass.zep on line 62

      this->_optionsx = options;
      ------------^

如果你想避免这个编译器验证或动态创建一个属性,您可以使用字符串的属性名通过"{}"将属性名包裹起来:

let this->{"myProperty"} = 100;

您还可以使用一个简单的变量更新属性,属性名称将从变量获取:

let someProperty = "myProperty";
let this->{someProperty} = 100;

##读属性##

属性可以通过“->”运算符获取:

echo this->myProperty;

当更新属性可以动态地读:

//避免编译器检查或动态的定义的属性
echo this->{"myProperty"};

//读取和使用一个变量名
let someProperty = "myProperty";
echo this->{someProperty}

##类的常量##

类是保持不变的,一旦扩展被编译的类常量就已经确认下来了。

namespace Test;

class MyClass
{

    const MYCONSTANT1 = false;
    const MYCONSTANT2 = 1.0;
}

类常量可以使用类名称和访问静态操作符(::):

namespace Test;

class MyClass
{

    const MYCONSTANT1 = false;
    const MYCONSTANT2 = 1.0;

    public function someMethod()
    {
        return MyClass::MYCONSTANT1;
    }
}

##调用方法##

方法可以被使用在PHP对象操作符(- >)调用:

namespace Test;

class MyClass
{

    protected function _someHiddenMethod(a, b)
    {
        return a - b;
    }

    public function someMethod(c, d)
    {
        return this->_someHiddenMethod(c, d);
    }
}

静态方法必须调用使用静态操作符(::):

namespace Test;

class MyClass
{

    protected static function _someHiddenMethod(a, b)
    {
        return a - b;
    }

    public static function someMethod(c, d)
    {
        return self::_someHiddenMethod(c, d);
    }
}

你可以以动态的方式调用方法如下:

namespace Test;

class MyClass
{
    protected adapter;

    public function setAdapter(var adapter)
    {
        let this->adapter = adapter;
    }

    public function someMethod(var methodName)
    {
        return this->adapter->{methodName}();
    }
}

##参数的命名##

ZEPHIR支持名称或关键字参数调用方法的参数。如果你想通过以任意顺序参数,记录参数的含义或以更优雅的方式指定参数命名参数可以是有用的。

考虑下面的例子,一个名为“Image”类有接收四个参数的方法:

namespace Test;

class Image
{
    public function chop(width = 600, height = 400, x = 0, y = 0)
    {
        //...
    }
}

使用标准方法的调用方法:

i->chop(100); // width=100, height=400, x=0, y=0
i->chop(100, 50, 10, 20); // width=100, height=50, x=10, y=20

使用命名参数,您可以:

i->chop(width: 100); // width=100, height=400, x=0, y=0
i->chop(height: 200); // width=600, height=200, x=0, y=0
i->chop(height: 200, width: 100); // width=100, height=200, x=0, y=0
i->chop(x: 20, y: 30); // width=600, height=400, x=20, y=30

当编译器在编译时不知道这些参数的正确顺序 他们必须解决在运行时,在这种情况下,可能会有一个最小附加额外的开销:

let i = new {someClass}(); i->chop(y:30, x: 20);

##总结##

那么到这里关于zephir类方法相关的知识就已经结束了,那么从下节开始将讲解内置的一些方法函数的使用,已经流程控制语句,希望大家喜欢!

应为确实zephir的类方法这一块的类容比较多,笔者在这里分成两个小节进行说明,多谢大家的支持!

注:笔者能力有限有说的不对的地方希望大家能够指出,也希望多多交流!

zephir技术交流:246348908 欢迎大家的加入!

感谢zephir开发人员: