在 php 8.1 发布之后,
readonly
user
order
configuration
然而,在实际开发中,我们常常会遇到一个看似矛盾的需求:我有一个不可变对象,但我想基于它创建一个“新版本”,仅仅修改其中一两个属性,而保持原始对象不变。例如,一个
Post
Post
<pre class="brush:php;toolbar:false;">class Post
{
public readonly string $title;
public readonly string $author;
public readonly string $content;
public function __construct(string $title, string $author, string $content)
{
$this->title = $title;
$this->author = $author;
$this->content = $content;
}
}
$originalPost = new Post('旧标题', '张三', '这是一篇旧文章的内容。');
// 试图克隆并修改标题,但 readonly 属性不允许重新赋值!
// $newPost = clone $originalPost;
// $newPost->title = '新标题'; // 这会抛出错误!直接对
readonly
spatie/php-cloneable
正当我为这种重复而无趣的代码感到沮丧时,开源社区再次展现了它的强大力量。
spatie/php-cloneable
readonly
这个包的核心思想是:通过一个
with
立即学习“PHP免费学习笔记(深入)”;
spatie/php-cloneable
首先,通过 Composer 轻松安装它:
<pre class="brush:php;toolbar:false;">composer require spatie/php-cloneable
接下来,在你的类中引入
Spatie\Cloneable\Cloneable
<pre class="brush:php;toolbar:false;">use Spatie\Cloneable\Cloneable;
class Post
{
use Cloneable; // 引入 Cloneable Trait
public readonly string $title;
public readonly string $author;
public readonly string $content;
public function __construct(string $title, string $author, string $content)
{
$this->title = $title;
$this->author = $author;
$this->content = $content;
}
}
$originalPost = new Post('旧标题', '张三', '这是一篇旧文章的内容。');
// 现在,我们可以使用 with 方法来创建一个新 Post 实例,并修改其标题
$newPost = $originalPost->with(title: '新标题'); // 注意:这里必须使用命名参数!
echo "原始文章标题: " . $originalPost->title . PHP_EOL; // 输出: 旧标题
echo "新文章标题: " . $newPost->title . PHP_EOL; // 输出: 新标题
// 也可以同时修改多个属性
$postByLiSi = $originalPost->with(title: '李四的文章', author: '李四');
echo "李四的文章标题: " . $postByLiSi->title . ", 作者: " . $postByLiSi->author . PHP_EOL;
// 为了更好的可读性和封装性,你可以在类中定义特定的 with* 方法
class PostWithHelpers
{
use Cloneable;
public readonly string $title;
public readonly string $author;
public readonly string $content;
public function __construct(string $title, string $author, string $content)
{
$this->title = $title;
$this->author = $author;
$this->content = $content;
}
public function withTitle(string $title): self
{
return $this->with(title: $title);
}
public function withAuthor(string $author): self
{
return $this->with(author: $author);
}
}
$anotherPost = new PostWithHelpers('原创标题', '王五', '内容...');
$modifiedPost = $anotherPost->withTitle('修改后的标题')->withAuthor('赵六');
echo "修改后的文章标题: " . $modifiedPost->title . ", 作者: " . $modifiedPost->author . PHP_EOL;spatie/php-cloneable
with
readonly
readonly
with(propertyName: $value)
withPropertyName($value)
with
with*
spatie/php-cloneable
readonly
需要注意的是,
spatie/php-cloneable
with
spatie/php-cloneable
readonly
以上就是PHP8.1readonly属性克隆难题如何解决?spatie/php-cloneable助你轻松搞定!的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号