使用教义 3.1 - 在我的实体中,我有此专栏:
#[ORM\Column(type: 'blob')]
private $dataJpg;
如果我做到了
string
,PHP 会抱怨资源已被使用,并且在水合作用期间无法分配它。问题是我根本不想使用资源,我想要 string
形式的二进制数据。
在做 getter 时很容易使用资源:
public function getDataJpg(): ?string
{
$jpgData = $this->dataJpg;
/** @var resource|null $jpgData*/
if ($jpgData !== null) {
return stream_get_contents($jpgData);
}
return null;
}
但是对于二传手我不知道如何处理它。我得到了想要保留的
string
变量,但我无法将其分配给资源。解决方法是 fopen('php://memory')
但我不喜欢那样。
我需要一种方法来告诉原则将 blob 数据水合为字符串,这样我就可以只获取和设置字符串而不关心资源。
对于那些感兴趣的人,按照@BERKUT在评论中的建议,这是我制作的自定义类型:
<?php
declare(strict_types=1);
namespace App\DBAL\Types;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\ConversionException;
use Doctrine\DBAL\Types\Type;
class BlobStringType extends Type
{
/**
* {@inheritDoc}
*/
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
return $platform->getBlobTypeDeclarationSQL($column);
}
public function getName(): string
{
return 'blob_string';
}
/**
* {@inheritDoc}
*/
public function getBindingType(): ParameterType
{
return ParameterType::LARGE_OBJECT;
}
/**
* {@inheritDoc}
**/
public function convertToPHPValue($value, AbstractPlatform $platform): mixed
{
if ($value === null) {
return null;
}
if (is_string($value)) {
return $value;
}
if (! is_resource($value)) {
throw new ConversionException('Could not convert database value to string.');
}
if (stream_get_contents($value)) {
return stream_get_contents($value);
}
throw new ConversionException('Could not convert database value to string.');
}
/**
* {@inheritDoc}
*/
public function convertToDatabaseValue($value, AbstractPlatform $platform): mixed
{
if (is_null($value)) {
return null;
}
if (is_string($value)) {
$value = $this->convertStringToResource($value);
}
return $value;
}
/**
* @return resource
*/
public function convertStringToResource(string $value)
{
$fp = fopen('php://temp', 'rb+');
assert(is_resource($fp));
fwrite($fp, $value);
fseek($fp, 0);
return $fp;
}
}