搜索
首页后端开发php教程阵列接口的乐趣

Fun with Array Interfaces

关键要点

  • PHP 的数组接口允许程序员在自定义类中模拟原生数据类型的特性,类似于 Python 的方法。这使得自定义类能够像数组一样工作,并允许使用常见的数组操作,例如计数元素、循环遍历元素以及通过索引访问元素。
  • 接口就像类的契约,指定类必须包含的方法。它们允许封装实现细节并提供语法糖,从而提高代码的可读性和可维护性。PHP 提供了一个预定义接口库,可以实现这些接口以使对象类似于数组。
  • PHP 中的 CountableArrayAccessIterator 接口分别允许对象传递 count() 方法、像映射一样被访问以及迭代集合。这些接口可用于创建更动态和交互式的对象,例如可以计算其推文数量、循环遍历它们以及通过其 ID 访问推文的 Twitter 时间线类。

作为一名每天使用不同编程语言的程序员,我非常享受学习其他语言中不同的事物,并尝试在 PHP 中实现相同的功能。我特别喜欢 Python 中如何在自定义类中模拟原生数据类型的特性。

例如,这个成员列表类:

class Members {
    public function __construct(array $members) {
        $this->members = $members;
    }

    // 其他方法
}

通过实现 __iter__ 方法,您可以像迭代列表(PHP 中的数组)一样迭代此类实例中的数据:

class Members implements Iterator {
    private $members;
    private $position = 0;

    public function __construct(array $members) {
        $this->members = $members;
    }

    public function current() {
        return $this->members[$this->position];
    }

    public function key() {
        return $this->position;
    }

    public function next() {
        $this->position++;
    }

    public function rewind() {
        $this->position = 0;
    }

    public function valid() {
        return isset($this->members[$this->position]);
    }
}

$ls = new Members(["你", "我"]);

foreach ($ls as $member) {
    echo $member . "\n";
}

成员资格测试只需实现 __contains__ 方法:

class Members {
    public function __construct(array $members) {
        $this->members = $members;
    }

    public function contains($member) {
        return in_array($member, $this->members);
    }
}

$members = new Members(["你", "我"]);

if ($members->contains("我")) {
    echo "我是一个成员!\n";
}

我认为如果可以在自定义类的实例(不仅仅是数组)中在 PHP 中执行以下操作,那就太好了:

isset($myObject["test"]);

PHP 允许我们使用数组接口来实现这一点。

简述接口

将接口视为指定类必须包含的方法的契约。

interface Multiplier {
    public function multiply($num1, $num2);
}

使用此接口的任何类都必须具有此 multiply 方法。有一个关键字表示类满足此契约:implements

class SmartMultiplier implements Multiplier {
    public function multiply($num1, $num2) {
        return $num1 * $num2;
    }
}

只要满足契约,实现方式就无关紧要。实现 multiply 方法的另一种方法如下:

class NotSoSmartMultiplier implements Multiplier {
    public function multiply($num1, $num2) {
        $product = $num1;
        for ($i = 1; $i < $num2; $i++) {
            $product += $num1;
        }
        return $product;
    }
}

SPL 和 PHP 接口

PHP 提供了一个预定义接口库,只需在类中实现这些接口,就可以使我们的对象类似于数组。

其中一些接口包含在预定义接口和类列表中,一些包含在标准 PHP 库 (SPL) 中。

如果这些术语听起来令人生畏,请不要担心。您之前都使用过 $_GET$_GET 是一个被称为预定义的语言结构。

另一方面,根据文档,SPL 只是

一个旨在解决常见问题的接口和类集合。

现在要做的是看看这些接口的实际应用。让我们深入研究一下!

我们将创建一个 Twitter 时间线类,

class Members {
    public function __construct(array $members) {
        $this->members = $members;
    }

    // 其他方法
}

能够计算其推文数量,

class Members implements Iterator {
    private $members;
    private $position = 0;

    public function __construct(array $members) {
        $this->members = $members;
    }

    public function current() {
        return $this->members[$this->position];
    }

    public function key() {
        return $this->position;
    }

    public function next() {
        $this->position++;
    }

    public function rewind() {
        $this->position = 0;
    }

    public function valid() {
        return isset($this->members[$this->position]);
    }
}

$ls = new Members(["你", "我"]);

foreach ($ls as $member) {
    echo $member . "\n";
}

循环遍历它们,

class Members {
    public function __construct(array $members) {
        $this->members = $members;
    }

    public function contains($member) {
        return in_array($member, $this->members);
    }
}

$members = new Members(["你", "我"]);

if ($members->contains("我")) {
    echo "我是一个成员!\n";
}

并通过推文 ID 获取推文,

isset($myObject["test"]);

就像我们在普通数组中一样!

不过,我们必须先解决一些问题。如果您还没有 Twitter 帐户,请先创建一个。现在注册一个开发者帐户并生成访问令牌和密钥。

接下来,从 Github 下载或克隆代码,并在源文件夹内运行 composer install。如果您不熟悉 Composer,请参阅 SitePoint 之前的文章。打开 index.php 文件并添加必要的 OAuth 数据。

Countable 接口

Countable 接口可能是最不言自明的。只需实现 count 方法,就可以将对象传递给 count() 方法。

我们可以通过对“/users/show”执行 GET 请求来获取用户的推文数量。

interface Multiplier {
    public function multiply($num1, $num2);
}

ArrayAccess 接口

我们现在将通过学习一个更有趣的接口来提高难度。

实现后,ArrayAccess 将使我们的对象能够像映射一样被访问,这正是它们的本质。要实现的方法是

class SmartMultiplier implements Multiplier {
    public function multiply($num1, $num2) {
        return $num1 * $num2;
    }
}

这在我们的 Twitter 时间线对象中非常方便。测试推文是否存在于时间线中可以通过将我们的对象传递给 isset 来完成,如下所示:

class NotSoSmartMultiplier implements Multiplier {
    public function multiply($num1, $num2) {
        $product = $num1;
        for ($i = 1; $i < $num2; $i++) {
            $product += $num1;
        }
        return $product;
    }
}

为此,我们只需对推文 ID 执行 GET 请求。

$tweets = new Timeline("jeunito");

更好的是,我们还可以将上述内容用于 offsetGet,并让 offsetExists 依次调用 offsetGet

使用 offsetUnset,我们还可以通过推文 ID 进行删除,但我将把这留给您去实现。

不幸的是,实现 offsetSet 没有多大意义。对于这样的事情,简单的解决方法是抛出自定义异常,例如 UnsupportedOperationException。但另一方面,这也可能取决于您的应用程序的特定业务规则。

Iterator 接口

我把最喜欢的接口留到最后!Iterator 接口在这里非常有用,因为我认为没有比像迭代普通数组一样迭代时间线对象更好的方法来封装远程集合分页的细节了。

首先,需要实现以下方法:

count($tweets);

我们可以显式地使用上述方法来循环遍历我们的时间线,如下所示:

foreach ($tweets as $tweet) {
    echo $tweet;
}

但是,为什么这样做,当您可以这样做时:

// 获取
if (isset($tweets["some tweet id"])) {
    echo $tweets["some tweet id"];
}

在我们的示例中,我们将通过按时间顺序检索推文块并将它们存储在缓冲区中来循环遍历时间线中的推文。我们将迭代此缓冲区,直到它用尽,然后我们使用最后一个推文的 ID 作为偏移量来获取另一批推文。

最初我们没有任何推文,这就是 rewind 方法的用武之地:获取最新的 10 条推文,以便从我们可以获取接下来的 10 条推文的地方开始偏移。

class Members {
    public function __construct(array $members) {
        $this->members = $members;
    }

    // 其他方法
}

valid() 方法只是用于指示是否继续循环。这可以通过检查我们的推文缓冲区是否为空来完成:

class Members implements Iterator {
    private $members;
    private $position = 0;

    public function __construct(array $members) {
        $this->members = $members;
    }

    public function current() {
        return $this->members[$this->position];
    }

    public function key() {
        return $this->position;
    }

    public function next() {
        $this->position++;
    }

    public function rewind() {
        $this->position = 0;
    }

    public function valid() {
        return isset($this->members[$this->position]);
    }
}

$ls = new Members(["你", "我"]);

foreach ($ls as $member) {
    echo $member . "\n";
}

key()current() 方法只是返回我们迭代中当前推文的键和值。出于我们的目的,我们将简单地从缓冲区中获取推文 ID 和最新推文的文本。

class Members {
    public function __construct(array $members) {
        $this->members = $members;
    }

    public function contains($member) {
        return in_array($member, $this->members);
    }
}

$members = new Members(["你", "我"]);

if ($members->contains("我")) {
    echo "我是一个成员!\n";
}

最后是 next 方法。在这里,我们从缓冲区的头部出队以获取要迭代的下一个元素。然后,如果我们位于缓冲区的最后一个元素,我们将确保获取下一组推文。

isset($myObject["test"]);

我们完成了!这是一个非常基本的循环遍历用户推文的实现。还可以做更多的事情,例如本地缓存以节省 API 调用,但这就是使用接口的美妙之处:它们允许我们在后台更改我们的策略,只要我们的实现仍然正确,我们就可以期望它仍然有效。

但是现在,您可以通过在命令行中运行 php index.php 来观察我们的时间线对象的工作情况。

结论

接口的好处是双重的。它们允许我们封装实现细节并为我们提供语法糖,这两者在任何需要互操作性的应用程序中都非常有用。如果您有任何问题或意见,请在下面的评论部分留下它们!

以上是阵列接口的乐趣的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
可以在PHP会话中存储哪些数据?可以在PHP会话中存储哪些数据?May 02, 2025 am 12:17 AM

phpsessionscanStorestrings,数字,数组和原始物。

您如何开始PHP会话?您如何开始PHP会话?May 02, 2025 am 12:16 AM

tostartaphpsession,usesesses_start()attheScript'Sbeginning.1)placeitbeforeanyOutputtosetThesessionCookie.2)useSessionsforuserDatalikeloginstatusorshoppingcarts.3)regenerateSessiveIdStopreventFentfixationAttacks.s.4)考虑使用AttActAcks.s.s.4)

什么是会话再生,如何提高安全性?什么是会话再生,如何提高安全性?May 02, 2025 am 12:15 AM

会话再生是指在用户进行敏感操作时生成新会话ID并使旧ID失效,以防会话固定攻击。实现步骤包括:1.检测敏感操作,2.生成新会话ID,3.销毁旧会话ID,4.更新用户端会话信息。

使用PHP会话时有哪些性能考虑?使用PHP会话时有哪些性能考虑?May 02, 2025 am 12:11 AM

PHP会话对应用性能有显着影响。优化方法包括:1.使用数据库存储会话数据,提升响应速度;2.减少会话数据使用,只存储必要信息;3.采用非阻塞会话处理器,提高并发能力;4.调整会话过期时间,平衡用户体验和服务器负担;5.使用持久会话,减少数据读写次数。

PHP会话与Cookie有何不同?PHP会话与Cookie有何不同?May 02, 2025 am 12:03 AM

PHPsessionsareserver-side,whilecookiesareclient-side.1)Sessionsstoredataontheserver,aremoresecure,andhandlelargerdata.2)Cookiesstoredataontheclient,arelesssecure,andlimitedinsize.Usesessionsforsensitivedataandcookiesfornon-sensitive,client-sidedata.

PHP如何识别用户的会话?PHP如何识别用户的会话?May 01, 2025 am 12:23 AM

phpientifiesauser'ssessionusessessionSessionCookiesAndSessionIds.1)whiwSession_start()被称为,phpgeneratesainiquesesesessionIdStoredInacookInAcookInamedInAcienamedphpsessidontheuser'sbrowser'sbrowser.2)thisIdAllowSphptptpptpptpptpptortoreTessessionDataAfromtheserverMtheserver。

确保PHP会议的一些最佳实践是什么?确保PHP会议的一些最佳实践是什么?May 01, 2025 am 12:22 AM

PHP会话的安全可以通过以下措施实现:1.使用session_regenerate_id()在用户登录或重要操作时重新生成会话ID。2.通过HTTPS协议加密传输会话ID。3.使用session_save_path()指定安全目录存储会话数据,并正确设置权限。

PHP会话文件默认存储在哪里?PHP会话文件默认存储在哪里?May 01, 2025 am 12:15 AM

phpsessionFilesArestoredIntheDirectorySpecifiedBysession.save_path,通常是/tmponunix-likesystemsorc:\ windows \ windows \ temponwindows.tocustomizethis:tocustomizEthis:1)useession_save_save_save_path_path()

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具