使用 PHP 数组实现堆栈

首先,我们将为堆栈创建一个接口,这样我们就可以在不同的实现中使用堆栈,并确保所有实现之间具有一定的相似性。让我们为堆栈编写一个简单的接口:

Unresolved include directive in modules/ROOT/pages/ch04/ch4-02.adoc - include::example$Chapter04/1.php[]

从前面的接口可以看出,我们将所有堆栈函数都保留在了接口中,因为实现堆栈的类必须具备所有这些函数,否则在运行时会出现致命错误。由于我们使用 PHP 数组来实现堆栈,因此我们将使用一些现有的 PHP 函数来进行 pushpoptop 操作。我们将以这样一种方式来实现堆栈,即我们可以定义堆栈的大小。如果数组中没有项目,而我们仍想弹出,则会产生下溢异常;如果我们试图推送的项目超过数组容量,则会产生溢出异常。下面是使用数组实现堆栈的代码:

Unresolved include directive in modules/ROOT/pages/ch04/ch4-02.adoc - include::example$Chapter04/1.php[]

现在,让我们来看看为堆栈编写的代码。我们将栈的实现命名为 Books,但只要是有效的类名,我们可以随意命名。首先,我们使用 __construct() 方法构建堆栈,并选择限制堆栈中可存储的条目数。默认值为 20。下一个方法定义了 pop 操作:

Unresolved include directive in modules/ROOT/pages/ch04/ch4-02.adoc - include::example$Chapter04/1.php[]

如果堆栈不为空,pop 方法将返回一个字符串。为此,我们使用在栈类中定义的 empty 方法。如果堆栈为空,我们将从 SPL 抛出一个 UnderFlowException 异常。如果没有项要弹出,我们可以阻止该操作。如果堆栈不为空,我们将使用 PHP 中的 array_pop 函数从数组中返回最后一个项目。

push 方法中,我们的操作与 pop 相反。首先,我们检查堆栈是否已满。如果没有,我们就使用 PHP 的 array_push 函数将字符串项添加到栈的末尾。如果堆栈已满,我们将从 SPL 抛出 OverFlowException 异常。top 方法返回堆栈中最顶部的元素。isEmpty 方法检查堆栈是否为空。

由于我们遵循 PHP 7,因此我们在方法级别使用标量类型声明并使用方法的返回类型。

为了使用我们刚刚实现的堆栈类,我们必须想一个可以使用所有这些操作的例子。让我们编写一个小程序来制作一个书堆。代码如下:

Unresolved include directive in modules/ROOT/pages/ch04/ch4-02.adoc - include::example$Chapter04/1.php[]

我们为书籍堆栈创建了一个实例,用于保存编程书籍的标题。我们有三次推送操作。最后插入的书名是 "MySQL workbench tutorial"。如果我们在三次推送操作后弹出,返回的将是这个书名。之后,顶层将返回 "Mastering JavaScript",一旦执行了 pop 操作,它将成为顶层项。我们将整个代码嵌套在一个 try…​catch 块中,以便处理溢出和下溢抛出的异常。前面的代码将有如下输出:

MySQL Workbench tutorial
Mastering JavaScript

现在,让我们来关注一下刚才完成的不同堆栈操作的复杂性。