Avoid using dynamic array data structures in PHP - boreddev


This article presents an object-oriented approach to using Classes instead of using arrays in PHP. I will show you another perspective on why you should use Class / Object instead of arrays.


In the PHP world, using arrays (() or array ()) is too common. Array plays a very important role in PHP, but it also has its own limitations.


Consider the following example, assuming that you have a very long and complex code block. For illustrative purposes, we will assume a two-level deep block of code:


foreach (/* ... */) {
foreach (/* ... */) {
// thu thập dữ liệu data vào 1 mảng collection
}
}

Outside of this block, we will have an array of arrays to collect the data set inside the foreach loop.


$collection = (); // For later use.
foreach (/* ... */) {
$widget = ();
foreach (/* ... */) {
$widget = ...;
}
$collection() = $widget;
}
// Further use of $collection.

We have encountered or written the following code ourselves. The result is very easy to produce the following data structure:


$collection = (
(
'order' => (int),
'original' => (object),
'info' => (
'message' => (string),
'created_at' => (DateTime),
...
),
...
),
...
);

Dynamic data structures are always a bad approach. It is very likely that you (or someone else) will later have to expand this data structure and will not have a clear idea of ​​what the data structure will look like. You have to be careful about every line of code to make sure you are changing the right structure.


A better approach would be to use Classes as the data structure here. With Classes, you cannot create dynamically evolving data structures. Your data structure becomes uncertain (fixed). But this approach is not common in the PHP world, where people prefer to use arrays.


But in the example above, you should use Classes as well. Instead of using array, we now change it to objects.


class Collection {
/** @var Widget() */
private $widgets;

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

/** @return Widget() */
public function getWidgets(): array {
return $this->widgets;
}

/** @param Widget() $widgets */
public function setWidgets(array $widgets): void {
$this->widgets = $widgets;
}

/** @param Widget $widget */
public function addWidget(Widget $widget) {
$this->widgets() = $widget;
}
}

In the above code, we still use an array array for widgets, but at least it is surrounded by a class. Make sure we don't forget to initialize $ widgets in the constructor. Arrays inside a class should have an add () method. In this example we call it addWidget ().


Next, we create a Widget class:


class Widget {
/** @var int */
private $order;

/** @var SomeObject */
private $original;

/** @var Info */
private $info;

// More properties here.
...

public function __construct()
{
$this->order = 0;
}

// Getters and Setters here.
...
}

With the info field: we also create an Info class.


class Info {
/** @var string */
private $message;

/** @var DateTime */
private $createdAt;

// More properties here.
...

// Getters and Setters here.
...
}

Now change the loop code to use objects.


$collection = new Collection();
foreach (/* ... */) {
$widget = new Widget();
foreach (/* ... */) {
$widget->...;
}
$collection->addWidget($widget);
}

Conclude


Instead of using a sub-array data structure inside a parent array, we should create a dedicated class class, we should aim to use more classes. This is a good thing. And we should ensure there is a namespace dedicated to these data classes. App Data is a good suggestion.


The example in the article is an approach to using data structures more explicitly in PHP. This approach makes code easily maintainable for long-term PHP applications by avoiding the use of dynamic array data structures. Occasionally, you can still only use arrays, but you should rarely use them when possible.