Cannot modify readonly property error caused by MySQLI bind_param

Advertisements

Are PHP8.1 read-only properties compatible with bind_param?

Here is my constructor

public function __construct(
    private readonly ?bool $alreadyLive, //If true, the article is already live and will be updated. If false, it is a new article
    private readonly bool $pushLive, //If true, the article will be pushed live. If false, it will be saved in pending_articles
    private string $articleTitle,
    private string $articleExcerpt,
    private string $articleContent,
    private string $imageCard,
    private readonly string $articleType,
    private readonly string $articleStatus,
    private readonly ?int $articleNumber,
    private readonly int $authorID,
    private readonly int $heroPosition,
    databaseconnection $db
) {
    $this->db = $db;
}

I’m attempting to insert some data into a database like so:

    try {
        $sql = "INSERT INTO " . $table . " 
                    (title, author, content, excerpt, image_card, 
                    views, hero_position, type, status) 
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
        $stmt = $connection->prepare($sql);
        $stmt->bind_param("sisssiiss", 
                $this->articleTitle, $this->authorID, 
                $this->articleContent, $this->articleExcerpt, 
                $this->imageCard, $views, $this->heroPosition, 
                $this->articleType, $this->articleStatus
            );
        $stmt->execute();
        $article_id = $stmt->insert_id;
        $stmt->close();
    } catch (\Exception) {
        //Rollback the transaction
        $connection->rollback();

        //Return error message
        $response['status'] = 'error';
        $response['message'] = 'There was an error submitting your article. Please try again.';
        return $response;
    }

But I keep getting this error:

Cannot modify readonly property article::$authorID

Which is caused by this line as per the line in the stack trace:

$stmt->bind_param("sisssiiss", $this->articleTitle, $this->authorID, $this->articleContent, $this->articleExcerpt, $this->imageCard, $views, $this->heroPosition, $this->articleType, $this->articleStatus);

>Solution :

The error is absolutely correct. You cannot modify readonly properties, but you also cannot use them in a write context. In PHP, passing parameters by reference is considered a read-write operation. Thus you are not allowed to pass readonly properties to bind_param() just as you are not allowed to pass constants or literals.

To overcome this problem, use execute() and pass the values as an array.

$stmt = $mysqli->prepare();
$stmt->execute([
    $this->articleTitle,
    // ...
]);

Or since PHP 8.2, you can use execute_query():

$mysqli->execute_query($sqlQuery, [
    $this->articleTitle,
    // ...
]);

Leave a ReplyCancel reply