Symfony 2 ContextErrorException Only variables should be passed by reference when running Doctrine migration

1.5k Views Asked by At

When I run my Doctrine Migration I get the following error:

Migration 20141217162533 failed during Execution. Error Runtime Notice: Only variables should be passed by reference

[Symfony\Component\Debug\Exception\ContextErrorException] Runtime Notice: Only variables should be passed by reference

on the $this->validateUsername line. When I comment this out it works fine.

This seems like a very strange runtime error to experience and I cannot see why I am getting this.

public function up(Schema $schema)
{
    foreach ($this->old_users as $old_user) {
        if ($this->validateUsername($old_user['email']) === false or $this->checkDNSRecord($old_user['email']) === false) {
            $this->addSql("INSERT INTO User (email, joined_on, unsubscribed) VALUES ('" . $old_user['email'] . "', '" . $old_user['joined_on'] . "', 0)");
        }
    }
}

/**
 * Validate the username/email address based on the structure (e.g. [email protected])
 *
 * @param $email
 *
 * @return bool
 */
public function validateUsername($email)
{
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        // email is NOT valid
        return false;
    } else {
        // email is valid
        return true;
    }
}

/**
 * Validate the MX line of the DNS record for the host of the email address (e.g. @aol.co.uk)
 *
 * @param $email
 *
 * @return bool
 */
public function checkDNSRecord($email)
{
    if (checkdnsrr(array_pop(explode('@', $email)), 'MX')) {
        return true;
    } else {
        return false;
    }
}
2

There are 2 best solutions below

0
On BEST ANSWER

The problem is that functions like array_pop takes the array by reference since it changes it's content (removes the last element from the array). Now, you are passing the result of explode directly into array_pop array_pop(explode('@', $email)) therefore, php can't pass that result by reference because it's not a variable. The solution is quite simple, just keep explode result in a temp variable:

<?php
/* ... */
$mailParts = explode('@', $email);
checkdnsrr(array_pop($mailParts), 'MX');
/* ... */
0
On

Does this work better ?

public function up(Schema $schema)
{
    foreach ($this->old_users as $old_user) {
        $old_email = $old_user['email'];
        if ($this->validateUsername($old_email) === false or $this->checkDNSRecord($old_user['email']) === false) {
            $this->addSql("INSERT INTO User (email, joined_on, unsubscribed) VALUES ('" . $old_user['email'] . "', '" . $old_user['joined_on'] . "', 0)");
        }
    }
}