Letou nhà cái đánh giá

we’re sure that post implements WP_Post_Interface

we’re sure that post implements WP_Post_Interface

Want to learn object-oriented programmming.
Get my free course Using inheritance with WordPress.
As a WordPress developer, you’re always looking for ways to better reuse your code between projects.
Your time is valuable and you don’t want to reinvent the wheel each time you start a new project.
Object-oriented programming can help you with that.
In a previous post, I covered why you should learn it.
Now it’s time to take things further by going over the main feature for code reuse.
You’ve probably heard about it before.
It’s called “inheritance“.
Inheritance, what’s that?.
Inheritance is about maximizing the code reuse between your classes.
It allows you to create a hierarchy between your classes.
That hierarchy creates a “is-a” relationship between your classes.
That’s why a lot of examples follow the formula: class Car extends Vehicle (Car is a Vehicle).
class Dog extends Animal (Dog is an Animal).
They aren’t practical examples, but they highlight that relationship.
The take away from those examples is that you need to learn to see the relationship between your classes.
Once that happens, you’ll be able to leverage inheritance to create reusable code for your projects.
Visibility revisited.
When I covered encapsulation, I mentioned three possible access levels for properties and methods.
Public.
Private.
Protected.
“Public” meant that anyone could access the property or method.
Meanwhile, “Private” meant the opposite.
You could only access it internally.
It’s time to flesh out those definitions a bit more.
When using inheritance, defining a property or method as private restricts it to the class that defined it.
Its children can’t access it.
Meanwhile, protected grants access to the entire class hierarchy.
This means that child classes can access it.
The inheritance toolkit.
Before going ahead with a practical example, let’s go over some of the tools that you can use with inheritance.
A good understanding of that toolkit will allow you to leverage inheritance to its full potential.
Interfaces.
Interfaces are the most basic tool in your inventory.
You should see an interface as a contract.
By implementing an interface, your class agrees to implement specific methods.
You can only define public methods in an interface.
By only offering a contract, you let others worry about the implementation.
All that you care about is that the methods in your contract exist.
Let’s look at a small example.
interface Post_Interface { /** * Get the CSS class.
* * @return string */ public function get_class(); /** * Get the post type.
* * @return string */ public function get_type(); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 interface Post_Interface      * Get the CSS class.
get_class        * Get the post type.
get_type The Post_Interface represents a small contract for WordPress posts.
It has two methods: get_class and get_type.
Any class that implements Post_Interface will need to have these methods.
Built-in PHP interfaces.
PHP is full of useful interfaces that you can use to make your life easier.
For example, Countable allows you to pass your object to the built-in count function.

Class Posts implements Countable

{ /** * @var Post_Interface[] */ protected $posts; //.
public function count() { return count($this->posts); } } $posts = new Posts(); $num_posts = count($posts); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Posts implements Countable      * @var Post_Interface[] $posts     count count posts   $posts Posts   $num_posts count $posts The Posts class above contains multiple instances of Post_Interface objects.

Because Posts implements the Countable interface, we can pass Posts to the count function

This gives us an easy way to get the total number of  Post_Interface objects in Posts

Interface inheritance.
Interfaces can also inherit from other interfaces.
That’s the case with the built-in interface Traversable.
Traversable allows you to use your object in a foreach loop, but you can’t use it directly.
You need to implement either Iterator or IteratorAggregate which are its child interfaces.
class Posts implements IteratorAggregate { /** * @var array */ protected $posts; //.
public function getIterator() { return new ArrayIterator($this->posts); } } $posts = new Posts(); foreach ($posts as $post) { // Do stuff } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Posts implements IteratorAggregate $posts     getIterator ArrayIterator posts   $posts Posts   foreach $posts as // Do stuff This example shows our Posts  class implementing the IteratorAggregate.
There’s just a small problem.
We can’t have our getIterator return our posts array as is.
That’s because of the IteratorAggregate contract.
It says that getIterator needs to return an object implementing a Traversable interface.
Lucky for us, there’s a PHP class designed to turn an array into a Traversable object.
That’s why getIterator returns an instance of ArrayIterator.
It’s a class that turns an array into Traversable object.
Now, .

We can loop through the posts in our Posts class

Implementing multiple interfaces.
While a class can only have one parent class, it can implement as many interfaces as it wants.
This is a powerful feature of interfaces.
You can have a single class fulfill as many contracts as it wants.
class Posts implements Countable, IteratorAggregate { /** * @var array */ protected $posts; //.
Public function count() { return count($this->posts); } public function getIterator() { return new ArrayIterator($this->posts); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Posts implements Countable IteratorAggregate $posts     count count posts   getIterator ArrayIterator posts For example, .

Our Posts class now implements both Countable and IteratorAggregate

This lets you pass a Posts object inside the count function and in a foreach loop. Both will work.
Abstract classes.
Let’s say you want to reuse your code in your classes, but each class has just a tiny difference between how they behave.
You could implement it partially, but the other classes would need to do the rest of the work. That’s what abstract classes do.
They partially implement the logic in a class, but leave some details for the child classes.
Abstract methods are the methods that a child class needs to implement.
They function the same way as a method defined in an interface.
The one difference is that you can define an abstract method as protected.
You can view an abstract class as an interface where you already coded some of the logic.
You should know that, because they are incomplete, you can’t instantiate abstract classes.
abstract class Abstract_Post implements Post_Interface { /** * @var int */ protected $id; /** * Get the CSS class.
* * @return type */ public function get_class() { return $this->get_type().
”-”.
$this->id; } abstract public function get_type(); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Abstract_Post implements Post_Interface      * @var int        * Get the CSS class.
* @return type get_class get_type.
”-”.
get_type In the case of the Abstract_Post class shown above, we know some common details for all classes.
Every post will have a post ID.
It will also output its CSS class the same way.
get_class concatenates the post type and its ID together.
But we don’t know its post type yet.
That’s why get_type uses the abstract keyword.
It lets us use get_type in get_class without the need to code it.
We’ll leave that to the concrete classes.
Concrete classes.
Concrete classes are the classes that your code will end up using.
They might implement one or more interfaces and/or extend an abstract class.
The important thing is that you can instantiate these classes.

Class Attachment extends Abstract_Post { /** * Get the post type

* * @return string */ public function get_type() { return ”attachment”; } } $attachment = new Attachment(); $attachment->get_class(); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Attachment Abstract_Post      * Get the post type.
get_type ”attachment”   $attachment Attachment   $attachment get_class Now, it’s time to code the get_type method.
For our Attachment class, we make it return attachment.
It’s the same value as the existing WordPress post type.
Because we’ve completed our class, we can instantiate it and use it.
Overriding methods.
Here is a scenario: You defined a method in your parent class.
It works for 90% of the use cases, but not in that one child class.
What can you do.
Well, you can override the method.
You override a method by defining that method again in a child class.
Doing so replaces the old one and allows you to add that custom logic you wanted.
class Video extends Attachment { /** * Get the post type.
* * @return string */ public function get_type() { return ”video”; } } 1 2 3 4 5 6 7 8 9 10 11 12 Video Attachment      * Get the post type.
get_type ”video” In our Video class, we overrode our get_type method.
Instead of returning attachment, it’ll return video.
The parent method is still available if you want to use it.
All you need to do is use the parent keyword.
This is useful when you only want to alter the output of the parent method.
class Picture extends Attachment { /** * Get the post type.
* * @return string */ public function get_type() { return ”picture-”.
parent::get_type(); } } 1 2 3 4 5 6 7 8 9 10 11 12 Picture Attachment      * Get the post type.
get_type ”picture-”.
parent :: get_type In this final example, the get_type method for the Picture class won’t return attachment.
Instead, it’ll return picture-attachment.
attachment comes from our call to parent::get_type().
Final keyword.
There might be some cases where you don’t want others to extend your class or override your method. That’s where the final keyword comes in.
It prevents someone from extending a class or overriding a method.
There’s rarely a case for a class to be final, but you might see final methods in some cases.
You generally use a final method when the method is crucial to the functioning of a class.
In that case, overriding the method might have dire consequences.
Making sure you get the right type of object.
How can you make sure that you are receiving the correct type of object in your code.
You don’t want errors because someone didn’t give you the correct object.
Let’s look at two options available to you so you don’t get errors in your code.
Type hinting.
Type hinting is a useful tool when using inheritance.
It allows you to force a function or method to accept only a specific type as a parameter.
This saves you the need to do the validation in your code.
That said, receiving an invalid parameter will cause a fatal error in PHP.
/** * Save post to the database.
* * @param WP_Post_Interface $post */ function save_post(WP_Post_Interface $post) { // You are sure $post implements WP_Post_Interface } 1 2 3 4 5 6 7 8 9 * Save post to the database.
* @param WP_Post_Interface $post save_post WP_Post_Interface // You are sure $post implements WP_Post_Interface Validating in your code.
You can also check the object type in your code as well.
PHP has two ways for you to do it.
You can use either the is_a function or the instanceof operator.
This is how WordPress likes to do it since it allows for defensive coding.
Using this form of validation prevents PHP fatal errors.
/** * Save post to the database.
* * @param mixed $post */ function save_post($post) { // You are not sure $post implements WP_Post_Interface if (!$post instanceof WP_Post_Interface) { return; } // You are sure $post implements WP_Post_Interface } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 * Save post to the database.

* @param mixed $post save_post // You are not sure $post implements WP_Post_Interface

instanceof WP_Post_Interface // You are sure $post implements WP_Post_Interface The point of the above example is to show the before and after state within our save_post method.
Before our instanceof check, our post variable could be anything.
But after it, we’re sure that post implements WP_Post_Interface.
What should you check?.
That’s the better question to ask.
Is it the correct class or just an interface.
While it’s up to you, using interfaces for validation allows for the most flexibility.
When you’re validating a class, you’re telling them how to interact with your code.
You’re asserting more control over it as a result.
They have to use your class or they can’t do anything.
Validating using an interface allows others to build what they want.
You’re not forcing them to use your classes.
You just want them to use the contract that you created.
A practical example with WP_Widget.
WordPress widgets are an excellent showcase on how to use inheritance.
There is a clear relationship between the WP_Widget class and all its children.
That distinct relationship allows for a large amount of code reuse.
You can see the impact of it by the small size of the child classes.
How it currently works.
To develop your own custom widget, you need to extend the WP_Widget class and add your own logic.
WordPress expects you to override the widget method.
Otherwise, it will throw a fatal error.
class WP_Test_Widget extends WP_Widget { public function widget($args, $instance) { echo ”test”; } } 1 2 3 4 5 6 7 WP_Test_Widget WP_Widget widget $args $instance ”test” You can find more information about making widgets in the codex.
Leveraging inheritance.
As an exercise, let’s rewrite parts of the code to use inheritance.
This should give you a good idea of how to use the tools described earlier.
Defining an interface.

Let’s start by defining the interface WP_Widget_Interface

You want to create a baseline contract for all widgets in WordPress.
By doing so, we establish which methods WordPress deems necessary for a widget class.

Interface WP_Widget_Interface { /** * Register the widget

*/ public function register(); /** * Echo the widget content.
* * @param array $args * @param array $instance */ public function widget($args, $instance); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 interface WP_Widget_Interface      * Register the widget.
* Echo the widget content.
* @param array $args      * @param array $instance widget $args $instance You’ll notice that the interface has only two methods.
This isn’t a mistake.
You want to limit the interface to required methods only.
The only public methods that WordPress uses are register and widget.
All other methods are internal.
It is worth noting that some methods need to be public due to the nature of the callback system.
That said, they should not be part of the interface.
WordPress does not need to be aware of them for you to fulfill your contract.
Taking a look at WP_Widget.
Now that we have defined an interface for widgets, let’s take a better look at the WP_Widget class.
Let’s rework it while maintaining the behaviour expected by WordPress.
Managing property and method visibility.
WP_Widget uses only public methods and properties.
The documentation defines private methods as methods meant for internal use.
We’re going to rework the visibility of the methods and properties.
That’s because we want them to follow encapsulation principles.
This means that only a few functions are public.
There’s the register and widget methods.
We defined those in the interface.
Also, you have the three callback methods which should also be public.
All other methods are for internal use only.
This means that you should define those methods as “protected”.
This goes for the properties as well.
Using an abstract class.
The WP_Widget class is an ideal candidate for an abstract class.
WordPress expects each child object to implement its own widget method.
By using an abstract class, we’re deferring the need to implement the method to the child class.
No need to use a “die”.
Using the final keyword.
WP_Widget documentation highlights methods that shouldn’t be overridden but leaves it at that.
We’re going to use the final keyword to lock down those methods.
We are, again, formalizing a behaviour that WordPress expects.
The result.
You can see the result below.
This isn’t an exact copy of all the methods.
It highlights the changes discussed earlier.
abstract class Abstract_WP_Widget implements WP_Widget_Interface { /** * @var array */ protected $widget_options; /** * @var string */ protected $id_base; /** * @var string */ protected $name; /** * @var array */ protected $control_options; /** * @var bool */ protected $number = false; /** * @var bool */ protected $id = false; /** * @var bool */ protected $updated = false; /** * Constructor * * @param type $id_base * @param type $name * @param type $widget_options * @param type $control_options */ public function __construct( $id_base, $name, $widget_options = array(), $control_options = array() ) { } /** * {@inheritdoc} */ final public function register() { } /** * Generate the actual widget content.
*/ final public function display_callback($args, $widget_args = 1) { } /** * Generate the control form.
*/ final public function form_callback($widget_args = 1) { } /** * Deal with changed settings.
* * @param mixed $deprecated Not used.
*/ final public function update_callback($deprecated = 1) { } /** * Echo the settings update form.
* * @param array $instance Current settings */ protected function form($instance) { } /** * Constructs name attributes for use in form() fields.
* * @param string $field_name * * @return string */ protected function get_field_name($field_name) { } /** * Constructs id attributes for use in form() fields.
* * @param string $field_name * * @return string */ protected function get_field_id($field_name) { } /** * Update a widget instance.
* * @param array $new_instance * @param array $old_instance * * @return array */ protected function update($new_instance, $old_instance) { } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 Abstract_WP_Widget implements WP_Widget_Interface      * @var array $widget_options      * @var string $id_base      * @var string      * @var array $control_options      * @var bool $number false      * @var bool false      * @var bool $updated false        * Constructor      * @param type $id_base      * @param type $name      * @param type $widget_options      * @param type $control_options $id_base $widget_options $control_options        * {@inheritdoc} final        * Generate the actual widget content.
final display_callback $args $widget_args 1        * Generate the control form.
final form_callback $widget_args 1        * Deal with changed settings.
* @param mixed $deprecated Not used.
final update_callback $deprecated 1        * Echo the settings update form.
* @param array $instance Current settings $instance        * Constructs name attributes for use in form() fields.
* @param string $field_name      * get_field_name $field_name        * Constructs id attributes for use in form() fields.
* @param string $field_name      * get_field_id $field_name        * Update a widget instance.
* @param array $new_instance      * @param array $old_instance update $new_instance $old_instance Changing the validation in WordPress.
We have a proper interface for widgets.
We can make changes to the_widget function.
Instead of validating based on the WP_Widget class, we will use the interface.
Function the_widget($widget, $instance = array(), $args = array()) { global $wp_widget_factory; $widget_obj = $wp_widget_factory->widgets[$widget]; if ( !is_a($widget_obj, .

”WP_Widget_Interface”) ) return; //

$widget_obj->widget($args, $instance); } 1 2 3 4 5 6 7 8 9 10 11 the_widget $widget $instance $args global $wp_widget_factory   $widget_obj $wp_widget_factory widgets $widget.
Is_a $widget_obj ”WP_Widget_Interface” $widget_obj widget $args $instance Meanwhile, .

WP_Widget_Factory should also validate an object to see if it’s a WP_Widget

It doesn’t.
That’s a bug I submitted to Trac.
Here is a possible way we could handle it.
class WP_Widget_Factory { var $widgets = array(); function register($widget_class) { $widget_obj = new $widget_class(); if ( !is_a($widget_obj, ”WP_Widget_Interface”) ) return; $this->widgets[$widget_class] = $widget_obj; } //.
} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 WP_Widget_Factory var $widgets   $widget_class $widget_obj $widget_class.
is_a $widget_obj ”WP_Widget_Interface”   widgets $widget_class $widget_obj   It comes down to practice.
Inheritance is one of the most powerful features of object-oriented programming.
The amount of time you save with the code reuse is incredible.
That said, it can also be the hardest thing to grasp for newcomers.
Being able to see the relationship between your classes takes time and practice.
So keep at it.
Tweet.
#Abstract class #Inheritance #Interface #Object-oriented Programming #PHP #Widget API # The first thing you should learn from object-oriented programming Polymorphism and WordPress: Abstract classes.


Amazon Opens Pre-Orders for Pokemon TCG Eternatus VMAX Premium Collection and V Powers Tin

x.
All Channels.
Favorites Popular Login / Join AnimeShinbun community now.
Amazon Opens Pre-Orders for Pokemon TCG Eternatus VMAX Premium Collection and V Powers Tin.
10d ago.
Amazon has opened pre-orders for Pokémon TCG: Eternatus VMAX Premium Collection, Pokémon TCG: V Powers Tin in addition to Pokemon TCG V Powers All 3 Tins: Pikachu V Eevee V, and Eternatus V.
Read Full Story >> TopNewestOldest The story is too old to be commented.
All.
News.
Reviews.
Screenshots.
Videos.
Previews.
Interviews.
Rumors.
Trailers.
Podcasts.
Videocasts.
Articles.
Images.
Opinion pieces.
Blog Posts.
Mixed.
Related.
New.
22m 1d 1d 5h 2d 2d 3d 18h 19h x x x.


CRank: 25 Score: 193150 Feed

x.
All Channels.
Favorites Popular Login / Join AnimeShinbun community now.
GamerGaming.
CRank: 25 Score: 193150 Feed.
Comments.
About.
All.
News.
Blog Posts.
29m 1d 2d 3d 4d 5d 6d 7d 8d 9d 10d 11d 12d 13d 14d Amazon Opens Pre-Orders for Dragon Ball Z Season 1, 2 and 3 Steelbook Blu-Ray Sets.
15d dayonecollectors.com 16d Amazon Opens Pre-Orders for Akame Ga Kill Complete Collection Steelbook Blu-Ray Set.
17d dayonecollectors.com 18d 19d Amazon Opens Pre-Orders for Gundam Build Divers Blu-Ray Set.
20d dayonecollectors.com Amazon Opens Pre-Orders for JoJo”s Bizarre Adventure Manga: Part 4 Diamond Is Unbreakable Vol.
7.

21d dayonecollectors.com 22d Amazon Opens Pre-Orders for Dr

Stone: Season One – Part One Blu-Ray Set

23d dayonecollectors.com 24d 25d Ghost in the Shell (1995) 4K UHD Set Dropped To Under $18.
26d dayonecollectors.com x x x.