Php 强制类属性的允许值或范围的最不草率的方法
假设我有一门课 class Main { $prop1 = 2; $prop2 = 23; ... $prop42 = "what"; function __construct($arg_array) { foreach ($arg_array as $key => $val) { $this->$key = $val; } } } 正如您在Php 强制类属性的允许值或范围的最不草率的方法,php,object,php-5.3,Php,Object,Php 5.3,假设我有一门课 class Main { $prop1 = 2; $prop2 = 23; ... $prop42 = "what"; function __construct($arg_array) { foreach ($arg_array as $key => $val) { $this->$key = $val; } } } 正如您在prop2中所看到的,我
prop2
中所看到的,我的验证函数开始变得非常混乱,因为有太多的“if-then-iterate”块,我不仅要考虑范围,还要考虑允许值的列表。有了验证代码和这个规则数组,我的脚本变得相当庞大
问题是,如何将我的类或类属性、验证代码或脚本的任何其他方面构造得尽可能简短,以允许属性范围和值强制?是否有语言特性或技巧可以更优雅地处理此问题?我是否已经达到了这门语言的极限?有没有其他语言的例子可以很容易地实现这一点,从而提供一些线索?getter和setter
class Main {
private $prop1;
private $prop2;
private $prop3;
public function __construct( $p1 , $p2 , $p3 )
{
$this->setProp1($p1);
$this->setProp2($p2);
$this->setProp3($p3);
}
public function setProp1($p1)
{
// conditional checking for prop1
if(!$ok) throw new Exception('problem with prop1');
$this->prop1 = $p1;
}
//.. and so on
}
接球手和接球手
class Main {
private $prop1;
private $prop2;
private $prop3;
public function __construct( $p1 , $p2 , $p3 )
{
$this->setProp1($p1);
$this->setProp2($p2);
$this->setProp3($p3);
}
public function setProp1($p1)
{
// conditional checking for prop1
if(!$ok) throw new Exception('problem with prop1');
$this->prop1 = $p1;
}
//.. and so on
}
前几天我遇到了类似的问题。下面是我要做的:
private $props;
private $rules;
function __construct($params) {
// or you can get the rules from another file,
// or a singleton as I suggested
$this->rules = array (array('type' => 'range', 'min' => 10, 'max' => 20),
array('type' => 'in_set', 'allowed' => array(1,2,3)));
for ($i=0; $i<count($params); $i++) {
if ($this->check($params[$i], $this->rules($i))
$this->props[$i] = $params[$i];
else
throw new Exception('Error adding prop ' . $i);
}
}
function check($value, $rule) {
switch($rule['type']) {
case 'range':
return ($rule['min'] <= $value && $value <= $rule['max']);
case 'in_set':
return (in_array($value, $rule['allowed']));
// and so on
}
}
private$props;
私人规则;
函数构造($params){
//或者你可以从另一个文件中获取规则,
//还是我建议的单身汉
$this->rules=array(数组('type'=>'范围','min'=>10,'max'=>20),
数组('type'=>'in_set','allowed'=>数组(1,2,3));
对于($i=0;$icheck($params[$i],$this->rules($i))
$this->props[$i]=$params[$i];
其他的
抛出新异常('添加属性'$i'时出错);
}
}
函数检查($value$rule){
开关($rule['type'])){
案例“范围”:
return($rule['min']前几天我遇到了类似的问题。下面是我要做的:
private $props;
private $rules;
function __construct($params) {
// or you can get the rules from another file,
// or a singleton as I suggested
$this->rules = array (array('type' => 'range', 'min' => 10, 'max' => 20),
array('type' => 'in_set', 'allowed' => array(1,2,3)));
for ($i=0; $i<count($params); $i++) {
if ($this->check($params[$i], $this->rules($i))
$this->props[$i] = $params[$i];
else
throw new Exception('Error adding prop ' . $i);
}
}
function check($value, $rule) {
switch($rule['type']) {
case 'range':
return ($rule['min'] <= $value && $value <= $rule['max']);
case 'in_set':
return (in_array($value, $rule['allowed']));
// and so on
}
}
private$props;
私人规则;
函数构造($params){
//或者你可以从另一个文件中获取规则,
//还是我建议的单身汉
$this->rules=array(数组('type'=>'范围','min'=>10,'max'=>20),
数组('type'=>'in_set','allowed'=>数组(1,2,3));
对于($i=0;$icheck($params[$i],$this->rules($i))
$this->props[$i]=$params[$i];
其他的
抛出新异常('添加属性'$i'时出错);
}
}
函数检查($value$rule){
开关($rule['type'])){
案例“范围”:
return($rule['min']现在他需要84个getter和setter。不确定这是否是个好主意。“set”函数的数量很容易通过使用_call()而减少到0。但是,现在我又回到了使用这么多“if thens”内部调用()来定义特殊情况验证每一种情况。我只是兜圈子,根本不减少代码。你是在试图避免编码。问题是,不管你用什么语法,都不会优化脚本,要冗长严格,让它编译到(可能相同或更快)操作码,使调试更容易,代码更干净,长期维护性更高。@nathan我实际上希望能有一个php编码示例,说明您的建议。除了您能否澄清“您所做的任何语法都不会优化脚本”。参见我发布的示例,关于“您所做的任何语法都不会优化脚本”,不管你试图变得多么短小和聪明,代码仍然必须做同样的工作,如果你做得越简洁,机器符文(操作码)的“真实”代码就越复杂:)现在他需要84个getter和setter。不确定这是否是个好主意。“set”函数的数量很容易通过使用_call()而减少到0。但是,现在我又回到了使用这么多“if thens”内部调用()来定义特殊情况验证每一种情况。我只是兜圈子,根本不减少代码。你是在试图避免编码。问题是,不管你用什么语法,都不会优化脚本,要冗长严格,让它编译到(可能相同或更快)操作码,使调试更容易,代码更干净,长期维护性更高。@nathan我实际上希望能有一个php编码示例,说明您的建议。除了您能否澄清“您所做的任何语法都不会优化脚本”。参见我发布的示例,关于“您所做的任何语法都不会优化脚本”,不管你试图变得多么短小和聪明,代码仍然必须做同样的工作,如果你做得越简洁,机器符文(操作码)的“真实”代码就越复杂:)现在他需要一个84的大整块体,如果在他的构造函数中有/else…-为什么要用oo呢?@Aircule你的例子基本上就是我现在正在做的。我的验证代码放在我的\uu构造函数()中
函数,我在其他地方有规则数组来减少混乱。我想我希望的是某种语言功能或技巧在这种情况下有所帮助。@Aircule使用count()当数组每次迭代的大小都相同时,循环内部是一个“坏主意”。这样做确实会减慢循环较长的脚本的速度。即使某个特定循环很小,正确地执行也是一个好主意,以避免养成坏习惯。@tsgrasser:这只是为了演示概念和算法。如果确实需要执行这样的优化,我们不妨回到C语言中的黑客代码,并使用指针黑客对数组进行迭代。@tsgrasser对这个问题并不重要。重要的是整体概念,示例只是帮助解释它。现在,他需要一个84 if/else的大整块,在他的构造函数中…-即为什么要去oo for那是什么?@Aircule你的例子基本上就是我现在正在做的。我的验证代码放在我的\uuu construct()
函数中,我在其他地方有规则数组来保持混乱。我想我希望的是某种语言功能或技巧在这种情况下有所帮助。@Aircule使用count()在循环内是一个“坏主意”,因为每次迭代时数组的大小都是相同的。这样做确实会减慢循环较长的脚本的速度。即使特定的循环很小,这样做仍然是一个好主意