作为previous question的后续问题,我要求解决问题,我试图找到一种以“可读”的方式表达任意标识符的方法。
上下文:我们正在使用实体(来自DDD的域模型对象),它们具有身份。此标识(映射到数据库主键)可以表示为字符串:'123'
,'ABC'
。
某些实体可以具有复合身份,即由两个或更多其他实体身份组成:array('123','ABC')
。< / p>
有时,我们想要打印这个身份,或者在只允许一个字符串的地方使用它(例如,在HTML <option>
值中)。这个过程必须是可预测和可逆的,即如何将其逆转回原始状态应该没有歧义。
当我们想要人工阅读此身份时,出于调试目的,更容易阅读123
,ABC
或123~ABC
而不是{{ 1}},这就是为什么我们不想使用a:2:{i:0;s:3:"123";i:1;s:3:"ABC";}
或serialize()
等内置函数。
json_encode()做得非常好,但是当在HTML中使用它时,引号必须正确编码,它变得非常难以理解:
json_encode()
我们可以使用一个很好的格式,就像这样:
<option value="["123","ABC"]">
发布HTML表单时,我们必须能够将此编码的身份恢复为原始状态:<option value="123~ABC">
以检索正确的实体。< / p>
最后,如果身份包含除字母和数字之外的其他字符,则格式变得很复杂(人性化)。
一些基本的例子:
array('123','ABC')
=&gt; '123'
'123'
=&gt; 'ABC'
'ABC'
=&gt; array('123','ABC')
(只是一个想法)
'123~ABC'
=&gt; 'string with non-alphanumeric, even non-àscìì char$'
对于包含其他字符的字符串,任何(或多或少复杂的)表示都是可接受的。结果字符串应仅包含ASCII字符,即使原始字符串包含非ASCII字符也是如此。整个过程必须完全可逆。
关于如何做到这一点的任何想法?
答案 0 :(得分:1)
str_replace( array('[',']','"',',') ,
array('','','','~'),
json_encode($stuff)
);
你的问题非常冗长,并没有“解释你真正想要实现的目标。”
答案 1 :(得分:1)
根据您在评论中提供的反馈,我建议您使用urlencode或rawurlencode
然后,您可以使用,
冒号创建atom-composition。
class Identifier {
static function encode(array $identifier) {
return implode(', ', array_map('rawurlencode', $identifier));
}
static function decode($identifier) {
return array_map('rawurldecode',
array_map('trim', explode(',', $identifier))
);
}
}
$identifier = array('111', 'abc');
var_dump($identifier);
$encoded = Identifier::encode($identifier);
var_dump($encoded);
$decoded = Identifier::decode($encoded);
var_dump($decoded);
答案 2 :(得分:0)
您可以使用2个特殊字符:
~
- 分隔符
*
- 转义字符(转义分隔符或转义字符本身)
示例:
array('123','ABC') => 123~ABC
array('12*3','A~BC') => 12**3~A*~BC
您可以为分隔符和转义字符选择不同的字符。如果选择的字符很少可用,那么字符串通常可以很好地读取。