How PHP interfaces actually change the behavior of classes
P粉289775043
2023-09-02 23:49:28
<p>According to the PHP documentation, </p>
<blockquote>
<p>Object interfaces allow you to create code that specifies which methods a class must implement without defining how those methods are implemented. </p>
</blockquote>
<p>Thus, an interface is like a class with predefined methods that still need to be accessed using the <code>-></code> notation</p>
<p>However, the ArrayAccess interface provides access to objects as arrays. Objects can be accessed using <code>$object->property</code> and <code>$object["property"]</code></p>
<p>I can't understand how ArrayAccess makes it possible to change the object syntax. I wrote a piece of code to try to replicate the effect of the <code>ArrayAccess</code> method<em>only one</em>, but it throws the error</p>
<pre class="brush:php;toolbar:false;">// Using the PHP ArrayAccess Interface
namespace A {
class myclass implements \ArrayAccess {
public function offsetExists($offset) { return true; }
public function offsetGet($offset) {
// changed behavior
return $this->{$offset} ?? null;
}
public function offsetSet($offset, $value) {}
public function offsetUnset($offset) {}
}
$myclass = new myclass();
$myclass->access = 'Interface';
echo $myclass['access']; // "Interface"
};
//Trying to implement my own ArrayAccess Interface
namespace B {
interface MyArrayAccess {
public function offsetGet($offset);
}
class myclass implements MyArrayAccess {
public function offsetGet($offset) {
// change behavior
return $this->{$offset} ?? null;
}
}
$myclass = new myclass();
$myclass->access = 'Interface';
echo $myclass['access']; // Fatal error: Uncaught Error: Cannot use object of type B\myclass as array
}
</pre>
<p>Please help me explain it correctly. Thank you</p>
I'm not saying that interfaces "change the behavior of a class", but that interfaces make extending class functionality easy.
To understand interface, as an object-oriented programming concept, we should first understand what problem it wants to solve.
What problem is "Interface" designed to solve?
An interface is a contract. This is how duck-typing is implemented in PHP. You need to think from the perspective of a library writer who wants to expose functionality to others. For example,
To ensure that library users know that
$person
needs to have agetName()
method, you can create a classPerson
> that has agetName()
method. Type declarations are then used to detect potential errors when the code is resolved.Suppose there is another library that feeds things with food:
Consider this...
Now, suppose the user wants to write a
Pet
class that can both eat and greet. Users don't want to have to write these features again just toPet
them.How to write
Pet
to use both theGreeter
andFeeder
libraries?Maybe this is the case?
Unfortunately, PHP does not support multiple inheritance . A class can only
extend
one class. The above code is not valid. So in the current situation, users can only use one of the libraries.Additionally, "name" might be a very different concept for different things (e.g., one might use
getName() to return
$first_name
and$last_name
代码>). There may not be a reasonable default implementation of thegetName()
method in your library class.So, as a library writer, you want his/her library to be as flexible as possible for the user. what can you do?
How to solve this problem using "interface" in PHP?
An interface is a declaration of method signature. This is a quick way to declare library requirements without concrete class/inheritance requirements.
Using interfaces you can override both libraries like this:
Greeter
LibraryFeeder
LibraryNo need for a specific class (or parent class inheritance), a class can implement multiple interfaces. So the following
Pet
class is completely valid in PHP:Now objects of this
Pet
class can be used with theGreeter
library and theFeeder
library.ArrayAccess
What about the interface?ArrayAccess The interface is not declared by a third-party interface library writer, but is written by a core PHP writer. The core PHP writer provides deeper support for this.
Somewhat like the interface we mentioned before, PHP provides functionality to the classes that implement it. But instead of providing the
Greeter
orFeeder
examples above, core PHP provides syntax sugar for classes that implement ArrayAccess. This means you can use simpler code when working with classes that implement the AccessAccess interface.In the official example,
If you implement them, replace these with:
You can use
$obj
with array-like syntax to make the code shorter: