Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 动态创建Yii FormModel对象(CFormModel)_Php_Forms_Class_Yii_Magic Methods - Fatal编程技术网

Php 动态创建Yii FormModel对象(CFormModel)

Php 动态创建Yii FormModel对象(CFormModel),php,forms,class,yii,magic-methods,Php,Forms,Class,Yii,Magic Methods,我正在开发一个应用程序,它涉及在高抽象级别生成表单(这是一个CMS应用程序)。我想动态创建CFormModel对象,并动态设置表单字段。我想我可以通过扩展CFormModel,然后动态创建表示表单字段的类属性(“Yii行话中的属性”)来实现这一点 举例说明,不要在以下类(在文件中定义)中指定登录表单: 我想这样做: class MyFormModel extends CFormModel { protected $_rules = array(); public functi

我正在开发一个应用程序,它涉及在高抽象级别生成表单(这是一个CMS应用程序)。我想动态创建CFormModel对象,并动态设置表单字段。我想我可以通过扩展CFormModel,然后动态创建表示表单字段的类属性(“Yii行话中的属性”)来实现这一点

举例说明,不要在以下类(在文件中定义)中指定登录表单:

我想这样做:

class MyFormModel extends CFormModel {

    protected $_rules = array();

    public function __construct($attributes=array(), $rules=array()) {

        foreach ($attributes as $i => $attr) {
            $this->{$attr} = ???; // <<== This is the key here
        }

        // pass in array of rules as described in Yii doc for CFormModel
        $this->_rules = $rules;
    }

    public function rules() {
        return $_rules;
    }
}
$myModelObj = new MyFormModel($attr, $rules);
其中:

$attr = array(
            'username',
            'rememberMe',
            'password',
        );
$rules = array(
            array('username, password', 'required'),
            array('rememberMe', 'boolean'),
            array('password', 'authenticate'), // assume function authenticate defined elsewhere
        );
请注意,在我试图完成的工作中,任何文件中都没有写“LoginClass”,它是在代码中动态创建的

这将允许我创建表单(在视图中)执行以下操作:

// based on http://www.yiiframework.com/doc/guide/1.1/en/form.view
<?php echo $wForm->textField($myModelObj,'username'); ?>
实际上,该行的代码是:

$this->{$attr};
那个???表示我不确定要分配给此的内容。在yiidoc示例中,它们只是将字段定义为公共类变量

我应该使用魔法吗


我在这里试图做的事情可能吗?

正如您可能知道的那样,Yii用于解析类似AR的属性

您在这里需要做的与Yii内部所做的类似

定义硬编码属性以存储所有自定义属性(如数组):
$\u data

这些数据将是一个数组,并将保存您在运行时添加的所有属性。您可能需要像Yii一样覆盖神奇的方法(setter、getter、isset)来挑战验证,以便首先从
$\u数据
属性持有者解析属性名称

您可以在查找所有类似
\uuuxxx
的方法中找到某种代码

如果您将AR属性处理复制到自定义类中,您将在您的级别上运行所有这些操作,并且当您的魔术方法无法解决它时,将返回到Yii

此外,我还将研究行为,因为您可以将许多常见函数委托给行为类

组件行为的使用

组件支持该模式,可以附加一个或多个行为。行为是一个对象,其方法可以通过收集功能而不是专门化(即普通类继承)的方式由其附加组件“继承”。一个组件可以附加多个行为,从而实现“多重继承”

行为类必须实现
IBehavior
接口。大多数行为可以从
CBehavior
基类扩展。如果行为需要附加到模型,则它也可以从模型扩展,或者实现模型指定的其他特性

要使用行为,必须首先通过调用行为的
attach()
方法将其附加到组件。然后我们可以通过组件调用行为方法:

// $name uniquely identifies the behavior in the component
$component->attachBehavior($name,$behavior);
// test() is a method of $behavior
$component->test();
可以像访问组件的普通属性一样访问附加的行为。例如,如果将名为tree的行为附加到组件,我们可以使用以下方法获取对此行为对象的引用:

$behavior=$component->tree;
// equivalent to the following:
// $behavior=$component->asa('tree');
可以暂时禁用行为,以便其方法无法通过组件使用。比如说,

$component->disableBehavior($name);
// the following statement will throw an exception
$component->test();
$component->enableBehavior($name);
// it works now
$component->test();
附加到同一组件的两个行为可能具有相同名称的方法。在这种情况下,第一个附加行为的方法将优先

当与一起使用时,行为更强大。行为在附加到组件时,可以将其某些方法附加到组件的某些事件。这样,行为就有机会观察或更改组件的正常执行流

行为的属性也可以通过其附加到的组件进行访问。属性包括公共成员变量和通过行为的getter和/或setter定义的属性。例如,如果行为具有名为xyz的属性,并且该行为附加到组件$a。然后我们可以使用表达式
$a->xyz
访问行为的属性

更多阅读:

$behavior=$component->tree;
// equivalent to the following:
// $behavior=$component->asa('tree');
$component->disableBehavior($name);
// the following statement will throw an exception
$component->test();
$component->enableBehavior($name);
// it works now
$component->test();