-
Notifications
You must be signed in to change notification settings - Fork 11k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[6.x] [PHP 7.4] Using Typed properties classes on SerializesModels causes error due Illuminate\Contracts\Database\ModelIdentifier #30494
Comments
Will need a little bit more code to reproduce the problem. How are you instantiating the mailable? Can you show how you're sending the mailable? |
Ok @driesvints. This code is currenty working under PHP 7.3.11-1+ubuntu18.04.1+deb.sury.org+1 and I'm working to migrate to PHP 7.4 adding new features as Typed Properties, Arrow Functions, etc... Here the trace (with some non related code removed): # /app/Models/User.php
<?php declare(strict_types=1);
namespace App\Models;
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Database\Eloquent\Model;
use Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Model implements AuthenticatableContract, JWTSubject
{
use Authenticatable;
/**
* @var string
*/
protected $table = 'user';
/**
* @var string
*/
public static string $foreign = 'user_id';
/**
* @var array
*/
protected $hidden = ['password'];
} # /app/Services/User/Confirm.php
<?php declare(strict_types=1);
namespace App\Services\User;
use App\Models;
use App\Services;
class Confirm
{
/**
* @param string $user
*
* @return \App\Models\User
*/
public static function start(string $user): Models\User
{
$user = Models\User::where('user', $user)->firstOrFail();
Services\Mail\Mailer::userConfirm($user);
return $user;
}
} # /app/Services/Mail/Mailer.php
<?php declare(strict_types=1);
namespace App\Services\Mail;
use Illuminate\Support\Facades\Mail;
use App\Mails;
use App\Models;
class Mailer
{
/**
* @param \App\Models\User $user
*
* @return void
*/
public static function userConfirm(Models\User $user)
{
static::queue(new Mails\User\Confirm($user), [$user->user]);
}
/**
* @param \App\Mails\MailAbstract $mail
* @param array $emails
*
* @return void
*/
protected static function queue(Mails\MailAbstract $mail, array $emails)
{
Mail::queue(static::options($mail, $emails));
}
/**
* @param \App\Mails\MailAbstract $mail
* @param array $emails
*
* @return \App\Mails\MailAbstract
*/
protected static function options(Mails\MailAbstract $mail, array $emails): Mails\MailAbstract
{
$mail->to(static::filter($emails));
return $mail;
}
/**
* @param array $emails
*
* @return array
*/
protected static function filter(array $emails): array
{
return array_values(array_unique(array_filter($emails, static function (string $value): bool {
return $value && filter_var($value, FILTER_VALIDATE_EMAIL);
})));
}
} # /app/Mails/User/Confirm.php
<?php declare(strict_types=1);
namespace App\Mails\User;
use App\Mails\MailAbstract;
use App\Models;
class Confirm extends MailAbstract
{
/**
* @var \App\Models\User
*/
public Models\User $user;
/**
* @var string
*/
public $subject = '';
/**
* @var string
*/
public $view = 'user.confirm';
/**
* @param \App\Models\User $user
*
* @return self
*/
public function __construct(Models\User $user)
{
$this->user = $user;
}
} # /app/Mails/MailAbstract.php
<?php declare(strict_types=1);
namespace App\Mails;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
abstract class MailAbstract extends Mailable
{
use Queueable, SerializesModels;
/**
* Build the message.
*
* @return self
*/
public function build(): self
{
return $this->view('emails.pages.'.$this->view);
}
} Thanks! |
No, everything is here. But it's hard to say if it's a "bug", it's how the current implementation works. Serializable classes us a proxy object The reason is simple: models are complex and have database connection stuff (Eloquent is ActiveRecord, after all) and can't be easily serialized => so a proxy object is used instead. Which means temporarily this property will receive a different value and this, as it stands right now, property type declarations can't be used for serializable objects in Laravel. I'm curious if this is even fixable without change of paradigm; but I don't know the code that well. As PHP 7.4 starts to get released and more people start using this new features, more stuff like this will pop up. |
Is easy to reproduce in any PHP 7.4 environment. You only need to set a typed property to a model on a Queueable and SerializesModels event. It will be a bug when Laravel officially supports PHP 7.4. But, can be fixed before that moment? |
I've attempted to fix this here: #30604 Any feedback is greatly appreciated. |
@driesvints also got this error [laravel 6.16], [PHP 7.4.3]
|
I ran into this issue today migrating to PHP 7.4. Thanks for posting this. |
Using this class definition:
Queue can not serialize properties due Typed property
App\Mails\User\Confirm::$user
.Error:
The text was updated successfully, but these errors were encountered: