Lädt...


🔧 Constants are no longer constant in PHP


Nachrichtenbereich: 🔧 Programmierung
🔗 Quelle: dev.to

I really hope that I am not opening a can of worms here because I think I have found something in PHP that I should not have. Something that should not exist: const mutable objects.

Yes, you read that correctly. Since PHP 8.1, any regular old object can be a constant, even mutable ones. Why is this a big deal? Well, because constants used to be constant and never change. This is no longer the case.

Here, have a quick taste:

<?php

class MyClass {
    public int $value = 1;
    public function set(int $value) { $this->value = $value; }
}

const MY_OBJECT = new MyClass();
// Equivalent to:
// define('MY_OBJECT', new MyClass());

echo MY_OBJECT->value . "\n";
MY_OBJECT->set(2);
echo MY_OBJECT->value . "\n";

// Prints:
// 1
// 2

Interesting.

A short history lesson
If you carefully read the documentation for the define() function in PHP, you will come across the following statement about constant values:

In PHP 5, value must be a scalar value (int, float, string, bool, or null). In PHP 7, array values are also accepted.

https://www.php.net/manual/en/function.define.php

Objects were clearly not intended to be constant values. While there was never an official reason given for this restriction, some argued that it was due to objects being inherently mutable.

With the addition of enums in PHP 8.1, it became possible to use enum cases as constant values. A very useful feature, indeed. Although the documentation for define() was never amended, the following code works as expected:

<?php

enum Suit {
    case Clubs;
    case Diamonds;
    case Hearts;
    case Spades;
}

const CLUBS1 = Suit::Clubs;
define('CLUBS2', Suit::Clubs);

This brings us back to the topic at hand: objects.

Enums are classes, and enum cases are objects

The PHP documentation tells us how enums ought to be classified:

The Enum itself is a class, and its possible cases are all single-instance objects of that class. That means Enum cases are valid objects and may be used anywhere an object may be used, including type checks.

https://www.php.net/manual/en/language.enumerations.overview.php

The second sentence is especially interesting. If an enum case can be used anywhere an object can be used, then is the inverse also true? Remember, enum cases can be used as constants. So what about objects?

<?php

class MyClass {
    public $foo = 123;
}

const MY_OBJECT = new MyClass();

In PHP 8.0 and earlier this code would terminate with an error, but starting with 8.1, it runs just fine.

Constant objects are a now thing (for better or worse).

Defining constant objects

We have already seen two ways to create constant objects: the declare() function and the const keyword at the top level. Both are functionally identical.

<?php

const MY_OBJECT1 = new MyClass();
declare('MY_OBJECT2', new MyClass());

Class constants, however, cannot be declared this way.

<?php

class Foo {
    // Fatal error: New expressions are not supported in this context
    public const MY_OBJECT = new MyClass();
}

Declaring a class constant requires a constant expression, which new MyClass() is not. But do you know what is a constant expression? Another constant! Meaning, we can declare object constants on the class level by reusing global constants.

<?php

const GLOBAL_MY_OBJECT = new MyClass();

class Foo {
    public const MY_OBJECT = GLOBAL_MY_OBJECT;
}

Interestingly, there seems to be a difference between const on the top level and const on the class level that is not mentioned in the documentation.

Using constant objects

When it comes to reading access and method calls, constant objects can be used like any regular object.

<?php

class MyClass {
    public $foo = 123;
    public function getFoo() { return $this->foo; }
    public function setFoo($value) { $this->foo = $value; }
}

const MY_OBJECT = new MyClass();

MY_OBJECT->foo;         // Read property.
MY_OBJECT->getFoo();    // Call function.
MY_OBJECT->setFoo(321); // Call mutating function.

Two things that are off limits, though, are assigning to a property (or offset) and creating a reference to a property.

<?php

// Fatal error: Cannot use temporary expression in write context
MY_OBJECT->foo = 456;
MY_OBJECT[0] = 789;
$x = &MY_OBJECT->foo;

This is not a limitation on the mutability of the object itself. As stated earlier, we can mutate the object through method calls. Rather, it is a limitation of the PHP compiler. From the compiler’s point of view, assigning to a property of a constant object is equivalent to assigning to a property of a temporary object.

<?php

// Fatal error: Cannot use temporary expression in write context
(new MyClass())->foo = 1;

To work around this restriction, we can assign the constant to a regular variable or return the constant from a function.

<?php

$myObject = MY_OBJECT;
$myObject->foo = 1;

function getMyObject() { return MY_OBJECT; }
getMyObject()->foo = 2;

The constant() function may also come in handy as it returns any constant by name, thereby circumventing the ‘temporary expression’ problem.

What do we take from it?

My suggestion is: do not use constant objects (enums aside).

They are counter-intuitive (due to their mutability) and also completely unnecessary. Plus, I am pretty sure that constant objects were never an intended feature in the first place. My theory is that they snuck into the language with the introduction of enums.

It would be for the best if constant objects got removed from the language.

The post Constants are no longer constant in PHP appeared first on hbgl.

...

🔧 Constants are no longer constant in PHP


📈 56.27 Punkte
🔧 Programmierung

🐧 Constant Maps in Golang (Constant Map)


📈 37.41 Punkte
🐧 Linux Tipps

📰 PHP Warning: Constant ABSPATH already defined in wp-config.php


📈 25.63 Punkte
🐧 Unix Server

📰 A Diet Based on Caloric Restriction Might Make You Live Longer. It'll Certainly Feel Like Longer.


📈 23.51 Punkte
📰 IT Security Nachrichten

🔧 Static Variables, Constants, and Methods


📈 22.35 Punkte
🔧 Programmierung

🕵️ An IDA Python script to extract information from string constants


📈 22.35 Punkte
🕵️ Reverse Engineering

🔧 Mastering Go: Guide to Type Declarations, Variables, and Constants


📈 22.35 Punkte
🔧 Programmierung

📰 Linux 6.11: Mehr Rust, Torvalds ergänzt "Runtime Constants"


📈 22.35 Punkte
📰 IT Nachrichten

📰 Protected API Calls and String Constants: Looting Dridex’s Candy Box


📈 22.35 Punkte
📰 IT Security

🔧 Swift 101: Understanding Types, Variables, and Constants


📈 22.35 Punkte
🔧 Programmierung

🔧 Introduction to Constants in GBase 8a MPP Cluster


📈 22.35 Punkte
🔧 Programmierung

📰 Protected API Calls and String Constants: Looting Dridex’s Candy Box


📈 22.35 Punkte
📰 IT Security

🔧 Constants in Solidity


📈 22.35 Punkte
🔧 Programmierung

🔧 July 10, 2024 Python | DataTypes, Variables, Constants


📈 22.35 Punkte
🔧 Programmierung

🔧 Code Smell 249 - Constants as Numbers


📈 22.35 Punkte
🔧 Programmierung

🔧 Proposal for making private method work on constants too


📈 22.35 Punkte
🔧 Programmierung

🔧 Constants in C++


📈 22.35 Punkte
🔧 Programmierung

🔧 What are Variables and Constants in Go? Explained With Examples


📈 22.35 Punkte
🔧 Programmierung

🔧 Variables, Shadowing, and Constants in Rust


📈 22.35 Punkte
🔧 Programmierung

🔧 Simplify SVG Management: Convert Paths to a Single JS File of Constants


📈 22.35 Punkte
🔧 Programmierung

🕵️ Binary ninja equivalent for symbolic constants?


📈 22.35 Punkte
🕵️ Reverse Engineering

🔧 Code Smell 262 - Not Replaced Constants


📈 22.35 Punkte
🔧 Programmierung

🔧 Constants in JS and what do Plato and Aristotle have to do with it


📈 22.35 Punkte
🔧 Programmierung

🕵️ CVE-2023-1712 | deepset-ai haystack prior 0.1.30 hard-coded, security-relevant constants


📈 22.35 Punkte
🕵️ Sicherheitslücken

🔧 PYTHON-FUNDAMENTALS: CONSTANTS, VARIABLES AND DATA TYPES


📈 22.35 Punkte
🔧 Programmierung

📰 Rust Basics Series #2: Using Variables and Constants in Rust Programs


📈 22.35 Punkte
🐧 Unix Server

🔧 Task 2 - Constants and variables


📈 22.35 Punkte
🔧 Programmierung

🔧 Variables and Constants: Declaration and Usage


📈 22.35 Punkte
🔧 Programmierung

🔧 10/7/24 - Day 2 - Data types,variables,constants


📈 22.35 Punkte
🔧 Programmierung

🍏 PCalc for iOS and Mac enhanced with new capabilities for functions, conversions, and constants


📈 22.35 Punkte
🍏 iOS / Mac OS

🕵️ CVE-2024-32021 | Git objects/ hard-coded, security-relevant constants


📈 22.35 Punkte
🕵️ Sicherheitslücken

📰 Humans and identity are constants in the ever-changing world of cybersecurity


📈 22.35 Punkte
📰 IT Security Nachrichten

🔧 Variables, Constants, Data Types, and Namespaces in C++


📈 22.35 Punkte
🔧 Programmierung

🕵️ XM^online Common Utils and Endpoints 0.2.1 Constants.java sql injection


📈 22.35 Punkte
🕵️ Sicherheitslücken

matomo