Category Archives: PHP

PHP 8.4: Property Hooks, Virtual Properties, and Potential Issues

This week the new version of PHP: 8.4 was released, with some new and shiny features. Well, technically it was 8.4.1, as 8.4.0 did not include some security patches so it never saw the light of day (strong PHP 6 vibes here 😀).

You can see the full list of changes in the migration guide, and I’ll highlight the one that brings me most joy.

Property Hooks

Do you ever grow tired of typing all the “getter” and “setter” methods for your class properties? Personally, I find it to be a meditative experience, and revisit the class architecture in my mind while my hands are busy with the keyboard. Call me old fashioned, but I never got used to generating them via IDE tools.

Well, with property hooks that mundane job just got easier, the code – cleaner, and developers – a little bit happier. Now you can define getters and setters right in the property definition, and they’ll be called every time the property is accessed. Works pretty much like magic methods assigned to a specific property.

class Sample {
        public string $foo = 'bar' {
                get => $this->foo . ' (bar-bar)';
                set => $value . ' (bar)';
        }
}

Every time you set the property value (e.g. $sample->foo = 'bar';), you get “(bar)” added to it. Every time you fetch the property value, you see an extra “(bar-bar)” in the end.

Neat, right? Wait, there’s more!

Virtual Properties and Accidental Fatals

Property hooks also introduce a sub-feature called “virtual properties”. It means that the property you declare doesn’t actually exist, and you cannot write into it. There’s one seemingly simple limitation – a virtual property cannot hold value, so no default value, no assignments, nothing. They also take up no memory, which is definitely a good thing.

The implementation is a bit tricky though, and may lead to errors down the line. You cannot explicitly define a property “virtual”. The property is considered virtual if neither get nor set helpers actually address it.

On one hand, it’s entirely logical, since we don’t really store any value in there. On the other hand, it makes our lives a bit harder because we need to make sure nobody accidentally turns a “backed” (regular) property into a “virtual”. Because if they do, they’ll trigger fatal errors if they miss out on refactoring.

For example, here we introduce a property and define a getter for it. We don’t need a setter, so we just omit it:

class Sample {
        public string $foo = 'bar' {
                get => $this->foo . ' (bar-bar)';
        }
}

Somewhere in the most unexpected part of code, a developer you never met assigns this property a value: $sample->foo = 'bar2';, and then proceeds to leave the company the next day.

Couple years later we decide to refactor that code, and turn the property virtual without even realizing that:

class Sample {
    public string $foo {
        get => 'virtual bar-bar';
    }
}

However, that random property value assignment is still there, and will go unnoticed until somebody runs that piece of code, triggering a fatal at the worst possible moment (as it usually happens):

Fatal error: Uncaught Error: Property Sample::$foo is read-only

Pretty much the same thing happens with properties accidentally turned into write-only virtual ones. If the property only has the “set” method defined, and it doesn’t write into anything the property, it will trigger a similar error:

class Sample {
    public string $foo {
        set => {
            echo $value . ' (virtual write-only set)';
            // Here we used to have "$this->foo = $value",
            // but we removed it without realizing we turned the property "virtual".
        }
    }
}

// Here we have some old code that trigger a fatal error as the property is virtual now.
echo $sample->foo;

// Fatal error: Uncaught Error: Property Sample::$foo is write-only

This is an unlikely scenario, but it’s still worth keeping in mind. However, it wouldn’t be a problem if the property had to be explicitly declared “virtual” (e.g. public virtual string $foo) to prevent it from being done inadvertently.

PHP 8.1: `never` Return Type is Dangerous

There are many features already introduced in PHP 8.1, and among them the new never return type:

function doSomething(): never {
    // do something
    die();
}

The idea is pretty straightforward: if the execution flow is never supposed to leave the function, it should be marked as never. If the execution flow somehow reaches the end of the function, PHP will throw an error.

Although it seems to me like a good idea, there’s a hidden catch we need to be cautious about.

Continue reading »

New Features in PHP 8

Two days ago the first “Alpha” of PHP 8 was presented, and PHP 8 is scheduled to release on November 26, 2020, only 5 months from now.

Looking back, I see how previous major releases took PHP to the next levels. I personally only witnessed two of them:

  • PHP 5 essentially revolutionized object-oriented programming in PHP. OOP in PHP 4 was not only insufficient, but also created terrifying number of legacy applications that relied on those deficiencies (I still find those &= in legacy code from time to time). In PHP 5 classes became usable, you could actually design an object-oriented architecture and not think about huge number of limitations (well, at least not as much).
  • PHP 7 took the language a few steps closer to those renowned enterprise-level languages as Java and C#. I’m a huge proponent of static type declarations, and although I appreciate the opportunities dynamic typing provides, it leads to many bugs that are easily preventable by declaring types.

So, What About PHP 8?

This release is going to be huge! There are so many RFC’s already merged and still being discussed, that I can’t wait to begin actually actually using it.

Let’s see what’s out there!

Continue reading »

Thanksgiving release of PHP 7.4

While most regular developers were enjoying time off with their families, the PHP dev team worked their best to bring new minor version of PHP with quite a few nice and useful features.

Everybody who follows the news of PHP world has already been excited about 7.4 for months, here’s a brief list of most important changes for those who missed it:

See the complete PHP 7.4 migration guide for details.

Besides the major improvements, there’s a minor one I feel strongly about: nested ternary operators with parentheses missing are now deprecated. I’m glad to see them thrown out of the door, it’s about time people stop using them.

From now on all eyes are on PHP 8, which has quite a few interesting RFC’s being discussed or developed, and some are already implemented.

User Roles and Access Control (ACL) in Laravel

It’s been over a year since I covered how to protect adminpanel routes in Laravel using Gates. Some people kept reminding me about my promise to cover ACL and user roles, and I kept putting off fulfilling that promise.

Finally I run into that on one of my projects, and that’s the sign I was waiting for to continue giving back to the community I learned so much from.

What is ACL

Although some computer science theorists enjoy using baffling definitions of the term (looking at you, MSDN), in reality it’s pretty simple and straightforward. ACL stands for Access Control List, and specifies what users are allowed to do.

There are three entities in the ACL:

  • User Role: e.g. admin, editor, reader
  • Object: e.g. blog post
  • Operation: create, edit, read, etc.
Continue reading »

Protect admin routes in Laravel

Today we’ll learn how to protect adminpanel and enhance authorization component of a Laravel application by adding user roles. We will assign each user with a role (e.g. superadmin, admin, member), create an Auth Gate, modify the User model, and utilize the Authenticate middleware to help them get along. Furthermore, we’ll build a skeleton of your future ACL system, which you can adjust and improve according to your needs.

Laravel provides us with a chance to save enormous amount of time on one condition – we should know how to use it. I’m pretty sure anybody who learned Laravel was not only impressed by how simple a complex task can be done, but also by complexity of seemingly simple tasks. The perfect example is authentication – you can create it with a single Artisan command and Laravel will take care of the rest. On the other hand, many beginners struggle with authorization and don’t know how to approach protecting the admin area. Obviously, it’s a trivial task if you have some PHP experience, but doing it the Laravel Way may be tricky.

Continue reading »

Namespaces in WordPress Plugins

Namespaces in WordPress

It’s no secret that many WordPress plugins are poorly designed. Some have been started as simple tools and grew larger until they became unmanageable, others were created by inexperienced developers who did their best. The sad truth is that WordPress provides complete freedom in designing plugins while many developers aren’t ready to take the responsibility. I’ll explain how I design plugins, and the cornerstone of this architecture is utilizing namespaces.

So why do we need namespaces in the first place? The most straightforward answer is shortening names of our classes and functions. Anybody who used to work with Zend Framework v1 (or almost every PHP framework created prior to PHP 5.3) has seen names like this: Zend_View_Helper_Placeholder_Container_Abstract. Imagine every single class name being this long and you get the idea. WordPress plugins often have the same problem – every class, every function you create has to have a unique name among all plugins ever created, so they often end up being too long to be convenient.

Continue reading »

Oblivious References and cURL Adventures

PHP references are tricky. They’ve always been. People question their performance, compliance with modern software architecture practices and trends. However, show me a single PHP language construct people do not question and I’ll buy you a beer.

I have to admit, it’s been much better since PHP5 came out. We do not have myriad of unintentionally cloned objects anymore, and the ampersand madness has stopped (however I know somebody who continues using it despite all the years passed since it lost its meaning):

$object =& new MyClass();

Don’t get me wrong, I love PHP, and I’ve been advocating its strength for years. Every time I heard somebody criticizing it I responded with a “You just don’t use it right” kind of answer, and was right every single time (well, you know, you can’t be wrong on the internet, it’s always the other guy who is wrong).
Continue reading »