《PHP 7擴(kuò)展開發(fā)之定義原生 Class》要點(diǎn):
本文介紹了PHP 7擴(kuò)展開發(fā)之定義原生 Class,希望對您有用。如果有疑問,可以聯(lián)系我們。
說到 Class 大家是不是首先就想到兩個(gè)字?復(fù)雜?哈哈,有這種想法其實(shí)真的很正常,因?yàn)樵诿嫦驅(qū)ο筮@個(gè)領(lǐng)域不得不說的就是類,隨便一想就有以下的知識點(diǎn):
字段定義
方法定義
父類
繼承
訪問控制
多態(tài)
一想頭就大,用 PHP 實(shí)現(xiàn)這些都挺麻煩的,更別是用 C++ 去實(shí)現(xiàn)了,如果大家使用過原生的 PHP 擴(kuò)展開發(fā)技術(shù)去定義個(gè)類,應(yīng)該就知道我說的意思了,但是還是那句話,在 zendAPI 中實(shí)現(xiàn)一個(gè) Class 真的不復(fù)雜,當(dāng)然我說特別簡單那是騙子.
考慮到咱們是新手入門教程,我們在本篇教程只實(shí)現(xiàn)一個(gè)簡單的類的定義,沒有繼承,不實(shí)現(xiàn)接口,沒有魔術(shù)方法,方法不使用引用傳參數(shù)也沒有可變參數(shù).
我們在本文中要實(shí)現(xiàn)的原生類原型用 PHP 描述大概是這樣的:
<?php
class Person
{
protected $name;
protected $age;
protected $address;
public function __construct($name, $age, $address)
{
$this->name = $name;
$this->age = $age;
$this->address = $address;
}
public function setName($name)
{
$this->name = $name;
}
public function setAge($age)
{
$this->age = $age;
}
public function setAddress($address)
{
$this->address = $address;
}
public function getName()
{
return $this->name;
}
public function getAge()
{
return $this->age;
}
public function getAddress()
{
return $this->address;
}
}
總的看來這個(gè)類很簡單,很適合我們進(jìn)行演示.下面我們對我們即將使用的一些關(guān)于定義原生類的知識點(diǎn)進(jìn)行簡單的解說,學(xué)習(xí)完這些知識點(diǎn)之后,有助于我們理解實(shí)現(xiàn)原生類的代碼.
#實(shí)現(xiàn)原生類涉及的知識點(diǎn)
#zapi::lang::StdClass
在 zendAPI 中,當(dāng)我們給 PHP 空間定義一個(gè)類的時(shí)候,您自己定義的 C++ 類必須繼承自 zapi::lang::StdClass, 這個(gè)類定義了很多以跟 PHP 空間同名的魔術(shù)函數(shù)供您使用.
比如:
void __destruct() const;
void __unset(const std::string &key);
Variant __invoke(Parameters ¶ms) const;
使用范例:
#include "zapi/lang/StdClass.h"
class SomeCustomCls : public zapi::lang::StdClass
{};
zapi::lang::StdClass 參考手冊 http://www.zendapi.org/api/classzapi_1_1lang_1_1_std_class.html
#zapi::lang::Class
在 zendAPI 項(xiàng)目里面我們用 zapi::lang::Class 去描述一個(gè) PHP 類的元信息,比如類的名字,有哪些字段有什么方法,是否 final 等等信息.基本上 zapi::lang::Class 有你實(shí)現(xiàn) PHP 的類所需要的一切.
使用范例: (定義一個(gè)名叫 SomeCustomCls 的 PHP 類的元信息對象)
#include "zapi/lang/StdClass.h"
class SomeCustomCls : public zapi::lang::StdClass
{};
zapi::lang::Class<SomeCustomCls> someCustomCls("SomeCustomCls");
zapi::lang::Class 參考手冊 http://www.zendapi.org/api/classzapi_1_1lang_1_1_class.html
#zapi::lang::Extension::registerClass
我們主要使用這個(gè)接口將類注冊到 zend engine 中,registerClass 是一個(gè)模板函數(shù),接受各種自定義類型的原生類的對象.
使用范例: (假設(shè) ext 是 zapi::lang::Extension 類型的對象,someCustomCls 是 zapi::lang::Class<SomeCustomCls> 類型的對象)
zapi::lang::Class<SomeCustomCls> someCustomCls("SomeCustomCls");
ext.registerClass(someCustomCls);
zapi::lang::Extension::registerClass 參考手冊
http://www.zendapi.org/api/classzapi_1_1lang_1_1_extension.html#1a0694f7f433033831dce669f02ede49ea
背景知識介紹完畢現(xiàn)在我們開始定義我們的 Person 類.
#第一步,定義 C++ 原生類
聲明原生類結(jié)構(gòu)
#include "zapi/ZendApi.h"
#include <string>
using zapi::ds::Variant;
using zapi::ds::NumericVariant;
using zapi::ds::StringVariant;
class Person : public zapi::lang::StdClass
{
public:
void __construct(const StringVariant &name, const NumericVariant &age,
const StringVariant &address);
void setName(const StringVariant &name);
void setAge(const NumericVariant &age);
void setAddress(const StringVariant &address);
Variant getName();
Variant getAge();
Variant getAddress();
protected:
int m_age;
std::string m_name;
std::string m_address;
};
實(shí)現(xiàn)原生類方法
#include "defs.h"
void Person::__construct(const zapi::ds::StringVariant &name,
const zapi::ds::NumericVariant &age,
const zapi::ds::StringVariant &address)
{
m_name = name.toString();
m_age = age.toLong();
m_address = address.toString();
}
void Person::setName(const zapi::ds::StringVariant &name)
{
m_name = name.toString();
}
void Person::setAge(const zapi::ds::NumericVariant &age)
{
m_age = age.toLong();
}
void Person::setAddress(const zapi::ds::StringVariant &address)
{
m_address = address.toString();
}
Variant Person::getName()
{
return m_name;
}
Variant Person::getAge()
{
return m_age;
}
Variant Person::getAddress()
{
return m_address;
}
到這里我們的原生類就實(shí)現(xiàn)完了,除了繼承自 zapi::lang::StdClass 沒有什么不一樣的.
#第二步, 實(shí)例化 zapi::lang::Class 對象,注冊原生方法
為了節(jié)省篇幅,這里我們假設(shè)這個(gè)代碼段定義在 get_module 函數(shù)體里,如果沒有印象了,請點(diǎn)擊
定義模塊入口 http://www.zendapi.org/manual/0.0.1/getstarted/definehellozapientry.html
Class<Person> personClass("Person");
personClass.registerMethod<decltype(&Person::__construct), &Person::__construct>
("__construct", {
ValueArgument("name", Type::String),
ValueArgument("age", Type::Long),
ValueArgument("address", Type::String)
});
personClass.registerMethod<decltype(&Person::setName), &Person::setName>
("setName", {
ValueArgument("name", Type::String)
});
personClass.registerMethod<decltype(&Person::setAge), &Person::setAge>
("setAge", {
ValueArgument("age", Type::Long)
});
personClass.registerMethod<decltype(&Person::setAddress), &Person::setAddress>
("setAddress", {
ValueArgument("address", Type::String)
});
personClass.registerMethod<decltype(&Person::getName), &Person::getName>("getName");
personClass.registerMethod<decltype(&Person::getAge), &Person::getName>("getAge");
personClass.registerMethod<decltype(&Person::getAddress), &Person::getName>("getAddress");
在這里我就不解釋注冊方法的使用了,基本上跟我們上一篇中注冊函數(shù)是一樣的,大家找找規(guī)律就能看懂了.
#第三步, 將 zapi::lang::Class 對象注冊到擴(kuò)展中
hellozapi.registerClass(personClass);
到這里我們就完整實(shí)現(xiàn)了我們的 Person 原生類,現(xiàn)在讓我們在 PHP 代碼中使用我們的 Person 類吧.
<?php
if (class_exists("Person")) {
echo "Person class exists\n";
$p1 = new Person("xiaomi", 22, "beijing");
$p2 = new Person("xiaohong", 27, "shanghai");
echo $p1->getName();
echo "\n";
echo $p1->getAge();
echo "\n";
echo $p1->getAddress();
echo "\n";
echo $p1->getName();
echo "\n";
echo $p1->getAge();
echo "\n";
echo $p1->getAddress();
// change some value
$p1->setName("zzu_softboy");
echo $p1->getName();
echo "\n";
$p2->setAge(33);
echo $p2->getAge();
}
// you will output
// xiaomi
// 22
// beijing
// xiaohong
// 27
// shanghai
// zzu_softboy
// 33
《PHP 7擴(kuò)展開發(fā)之定義原生 Class》是否對您有啟發(fā),歡迎查看更多與《PHP 7擴(kuò)展開發(fā)之定義原生 Class》相關(guān)教程,學(xué)精學(xué)透。維易PHP學(xué)院為您提供精彩教程。
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.snjht.com/jiaocheng/10629.html