Yii 学習 (5) -- アクティブ レコードの関連付け、yii --active_PHP チュートリアル

WBOY
リリース: 2016-07-13 10:20:23
オリジナル
1037 人が閲覧しました

Yii学習(5)--アクティブレコード協会、yii--active

公式サイト原文:http://www.yiiframework.com/doc/guide/1.1/zh_cn/database.arr

公式ウェブサイトの後半は英語で、中国語の内容は英語の内容よりも少ないです。最初にここに載せて、後で時間があるときに翻訳します。

アクティブ レコード (AR) を使用して単一のデータ テーブルからデータを取得する方法について見てきました。 このセクションでは、AR を使用して複数の関連データ テーブルを接続し、結合されたデータ セットを取得する方法について説明します。

リレーショナル AR を使用するには、関連付ける必要があるテーブルに主キーと外部キーの制約を定義することをお勧めします。これらの制約は、関連データの一貫性と整合性を確保するのに役立ちます。

簡単にするために、このセクションでは、以下に示すエンティティ関係 (ER) 図のデータ構造を使用して例を示します。

情報: 外部キー制約のサポートは DBMS によって異なります。 SQLite

1.関係を宣言する

AR を使用して関連クエリを実行する前に、ある AR クラスが別の AR クラスにどのように関連しているかを AR に知らせる必要があります。

2 つの AR クラス間の関係は、AR クラスによって表されるデータ テーブル間の関係を通じて直接関連付けられます。 データベースの観点から見ると、テーブル A とテーブル B の間には 1 対多 (例: tbl_user 和 tbl_post),一对一( one-to-one 例如 tbl_user 和tbl_profile)和 多对多(many-to-many 例如 tbl_category 和 tbl_post) という 3 つの関係があります。 AR には 4 種類の関係があります:

  • BELONGS_TO(属于): 如果表 A 和 B 之间的关系是一对多,则 表 B 属于 表 A (例如 Post 属于 User);

  • HAS_MANY(有多个): 如果表 A 和 B 之间的关系是一对多,则 A 有多个 B (例如 User 有多个 Post);

  • HAS_ONE(有一个): 这是 HAS_MANY 的一个特例,A 最多有一个 B (例如 User 最多有一个 Profile);

  • MANY_MANY: 这个对应于数据库中的 多对多 关系。 由于多数 DBMS 不直接支持 多对多 关系,因此需要有一个关联表将 多对多 关系分割为 一对多 关系。 在我们的示例数据结构中,tbl_post_category 就是用于此目的的。在 AR 术语中,我们可以解释 MANY_MANY 为 BELONGS_TO 和 HAS_MANY 的组合。 例如,Post 属于多个(belongs to many) Category ,Category 有多个(has many) Post.

AR で定義されたリレーションシップは、CActiveRecord の relationship() メソッドをオーバーライドする必要があります。このメソッドは、関係構成の配列を返します。配列の各要素は、次の形式で単一の関係を表します。

リーリー

ここで、VarName 是关系的名字;RelationType 指定关系类型,可以是一下四个常量之一: self::BELONGS_TO,self::HAS_ONEself::HAS_MANY and self::MANY_MANYClassName 是此 AR 类所关联的 AR 类的名字;ForeignKeyはリレーションシップで使用される外部キーを指定します。各関係の最後に追加のオプションを指定できます (これについては後で詳しく説明します)。

次のコードは、User 和 Post クラス間の関係を定義する方法を示しています。 リーリー

情報: 外部キーは、2 つ以上の列を含む複合キーである場合があります。 この場合、これらの外部キー名をスペースまたはカンマで区切ってリンクする必要があります。 指定の場合。 MANY_MANY 关系类型, 关联表的名字必须也必须在外键中指定。例如, Post中的 categories 关系由外键 tbl_post_category(post_id, category_id)

AR クラスの関係定義は、各関係のクラスに属性を暗黙的に追加します。相関クエリが実行されると、対応する属性に、関連付けられた AR インスタンスが設定されます。 たとえば、

インスタンスの場合。 $author 代表一个 User AR 实例, 我们可以使用 $author->posts 访问其关联的Post

2. 执行关联查询 

执行关联查询最简单的方法是读取一个 AR 实例中的关联属性。如果此属性以前没有被访问过,则一个关联查询将被初始化,它将两个表关联并使用当前 AR 实例的主键过滤。 查询结果将以所关联 AR 类的实例的方式保存到属性中。这就是传说中的 懒惰式加载(lazy loading,也可译为 迟加载) 方式,例如,关联查询只在关联的对象首次被访问时执行。 下面的例子演示了怎样使用这种方式:

<span>//</span><span> 获取 ID 为 10 的帖子</span>
<span>$post</span>=Post::model()->findByPk(10<span>);
</span><span>//</span><span> 获取帖子的作者(author): 此处将执行一个关联查询。</span>
<span>$author</span>=<span>$post</span>->author;
ログイン後にコピー

信息: 如果关系中没有相关的实例,则相应的属性将为 null 或一个空数组。 BELONGS_TOHAS_ONE关系的结果是 null, HAS_MANYMANY_MANY 的结果是一个空数组。 注意, HAS_MANYMANY_MANY 关系返回对象数组,你需要在访问任何属性之前先遍历这些结果。 否则,你可能会收到 "Trying to get property of non-object(尝试访问非对象的属性)" 错误。

懒惰式加载用起来很方便,但在某些情况下并不高效。如果我们想获取 N 个帖子的作者,使用这种懒惰式加载将会导致执行 N 个关联查询。 这种情况下,我们应该改为使用 渴求式加载(eager loading)方式。

渴求式加载方式会在获取主 AR 实例的同时获取关联的 AR 实例。 这是通过在使用 AR 中的 find 或 findAll 方法时配合使用 with 方法完成的。例如:

<span>$posts</span>=Post::model()->with('author')->findAll();
ログイン後にコピー

上述代码将返回一个 Post 实例的数组。与懒惰式加载方式不同,在我们访问每个 Post 实例中的 author 属性之前,它就已经被关联的 User 实例填充了。 渴求式加载通过 一个 关联查询返回所有帖子及其作者,而不是对每个帖子执行一次关联查询。

我们可以在 with() 方法中指定多个关系名字,渴求式加载将一次性全部取回他们。例如,如下代码会将帖子连同其作者和分类一并取回。

<span>$posts</span>=Post::model()->with('author','categories')->findAll();
ログイン後にコピー

我们也可以实现嵌套的渴求式加载。像下面这样, 我们传递一个分等级的关系名表达式到 with() 方法,而不是一个关系名列表:

<span>$posts</span>=Post::model()-><span>with(
    </span>'author.profile',
    'author.posts',
    'categories')->findAll();
ログイン後にコピー

上述示例将取回所有帖子及其作者和所属分类。它还同时取回每个作者的简介(author.profile)和帖子(author.posts)。

从版本 1.1.0 开始,渴求式加载也可以通过指定 CDbCriteria::with 的属性执行,就像下面这样:

<span>$criteria</span>=<span>new</span><span> CDbCriteria;
</span><span>$criteria</span>->with=<span>array</span><span>(
    </span>'author.profile',
    'author.posts',
    'categories',<span>
);
</span><span>$posts</span>=Post::model()->findAll(<span>$criteria</span>);
ログイン後にコピー

或者

<span>$posts</span>=Post::model()->findAll(<span>array</span><span>(
    </span>'with'=><span>array</span><span>(
        </span>'author.profile',
        'author.posts',
        'categories',<span>
    )
);</span>
ログイン後にコピー

3. 关系型查询选项

我们提到在关系声明时可以指定附加的选项。这些 名-值 对形式的选项用于自定义关系型查询。概括如下:

  • select: 关联的 AR 类中要选择(select)的列的列表。 默认为 '*',即选择所有列。此选项中的列名应该是已经消除歧义的。

  • condition: 即 WHERE 条件。默认为空。此选项中的列名应该是已经消除歧义的。

  • params: 要绑定到所生成的 SQL 语句的参数。应该以 名-值 对数组的形式赋值。此选项从 1.0.3 版起有效。

  • on: 即 ON 语句。此处指定的条件将会通过 AND 操作符附加到 join 条件中。此选项中的列名应该是已经消除歧义的。 此选项不会应用到 MANY_MANY 关系中。此选项从 1.0.2 版起有效。

  • order: 即 ORDER BY 语句。默认为空。 此选项中的列名应该是已经消除歧义的。

  • with: a list of child related objects that should be loaded together with this object. Be aware that using this option inappropriately may form an infinite relation loop.

  • joinType: type of join for this relationship. It defaults to LEFT OUTER JOIN.

  • alias: the alias for the table associated with this relationship. It defaults to null, meaning the table alias is the same as the relation name.

  • together: whether the table associated with this relationship should be forced to join together with the primary table and other tables. This option is only meaningful for HAS_MANY and MANY_MANY relations. If this option is set false, the table associated with the HAS_MANY or MANY_MANY relation will be joined with the primary table in a separate SQL query, which may improve the overall query performance since less duplicated data is returned. If this option is set true, the associated table will always be joined with the primary table in a single SQL query, even if the primary table is paginated. If this option is not set, the associated table will be joined with the primary table in a single SQL query only when the primary table is not paginated. For more details, see the section "Relational Query Performance".

  • join: the extra JOIN clause. It defaults to empty. This option has been available since version 1.1.3.

  • group: the GROUP BY clause. It defaults to empty. Column names referenced in this option should be disambiguated.

  • having: the HAVING clause. It defaults to empty. Column names referenced in this option should be disambiguated.

  • index: the name of the column whose values should be used as keys of the array that stores related objects. Without setting this option, an related object array would use zero-based integer index. This option can only be set for HAS_MANY and MANY_MANY relations.

  • scopes: scopes to apply. In case of a single scope can be used like 'scopes'=>'scopeName', in case of multiple scopes can be used like 'scopes'=>array('scopeName1','scopeName2'). This option has been available since version 1.1.9.

In addition, the following options are available for certain relationships during lazy loading:

  • limit: limit of the rows to be selected. This option does NOT apply to BELONGS_TO relation.

  • offset: offset of the rows to be selected. This option does NOT apply to BELONGS_TO relation.

  • through: name of the model's relation that will be used as a bridge when getting related data. This option has been available since version 1.1.7 where it can be used for HAS_ONE and HAS_MANY. Since 1.1.14 it can be used for BELONGS_TO as well.

Below we modify the posts relationship declaration in the User by including some of the above options:

<span>class</span> User <span>extends</span><span> CActiveRecord
{
    </span><span>public</span> <span>function</span><span> relations()
    {
        </span><span>return</span> <span>array</span><span>(
            </span>'posts'=><span>array</span>(self::HAS_MANY, 'Post', 'author_id',
                            'order'=>'posts.create_time DESC',
                            'with'=>'categories'),
            'profile'=><span>array</span>(self::HAS_ONE, 'Profile', 'owner_id'),<span>
        );
    }
}</span>
ログイン後にコピー

Now if we access $author->posts, we would obtain the author's posts sorted according to their creation time in descending order. Each post instance also has its categories loaded.

5. Disambiguating Column Names

When a column name appears in two or more tables being joined together, it needs to be disambiguated. This is done by prefixing the column name with its table's alias name.

In relational AR query, the alias name for the primary table is fixed as t, while the alias name for a relational table is the same as the corresponding relation name by default. For example, in the following statement, the alias name for Post and Comment is t and comments, respectively:

<span>$posts</span>=Post::model()->with('comments')->findAll();
ログイン後にコピー

Now assume both Post and Comment have a column called create_time indicating the creation time of a post or comment, and we would like to fetch posts together with their comments by ordering first the posts' creation time and then the comments' creation time. We need to disambiguate the create_time column like the following:

<span>$posts</span>=Post::model()->with('comments')->findAll(<span>array</span><span>(
    </span>'order'=>'t.create_time, comments.create_time'<span>
));</span>
ログイン後にコピー

Tip: The default alias of a related table is the name of the relation. Please note that if you're using relation from within another relation the alias will be the former relation name only and will not be prefixed with the parent relation. For example, the alias for 'author.group' relation is 'group', not 'author.group'.

<span>$posts</span>=Post::model()->with('author', 'author.group')->findAll(<span>array</span><span>(
  </span>'order'=>'group.name, author.name, t.title'<span>
));</span>
ログイン後にコピー

You can avoid the collision of tables' aliases by specifying the alias property of the relation.

<span>$comments</span>=Comment::model()-><span>with(
  </span>'author',
  'post',
  'post.author'=><span>array</span>('alias'=>'p_author'))->findAll(<span>array</span><span>(
  </span>'order'=>'author.name, p_author.name, post.title'<span>
));</span>
ログイン後にコピー

6. Dynamic Relational Query Options

We can use dynamic relational query options in both with() and the with option. The dynamic options will overwrite existing options as specified in the relations() method. For example, with the above User model, if we want to use eager loading approach to bring back posts belonging to an author in ascending order (theorder option in the relation specification is descending order), we can do the following:

User::model()->with(<span>array</span><span>(
    </span>'posts'=><span>array</span>('order'=>'posts.create_time ASC'),
    'profile',<span>
))</span>->findAll();
ログイン後にコピー

Dynamic query options can also be used when using the lazy loading approach to perform relational query. To do so, we should call a method whose name is the same as the relation name and pass the dynamic query options as the method parameter. For example, the following code returns a user's posts whose status is 1:

<span>$user</span>=User::model()->findByPk(1<span>);
</span><span>$posts</span>=<span>$user</span>->posts(<span>array</span>('condition'=>'status=1'));
ログイン後にコピー

7. Relational Query Performance

As we described above, the eager loading approach is mainly used in the scenario when we need to access many related objects. It generates a big complex SQL statement by joining all needed tables. A big SQL statement is preferrable in many cases since it simplifies filtering based on a column in a related table. It may not be efficient in some cases, however.

Consider an example where we need to find the latest posts together with their comments. Assuming each post has 10 comments, using a single big SQL statement, we will bring back a lot of redundant post data since each post will be repeated for every comment it has. Now let's try another approach: we first query for the latest posts, and then query for their comments. In this new approach, we need to execute two SQL statements. The benefit is that there is no redundancy in the query results.

So which approach is more efficient? There is no absolute answer. Executing a single big SQL statement may be more efficient because it causes less overhead in DBMS for parsing and executing the SQL statements. On the other hand, using the single SQL statement, we end up with more redundant data and thus need more time to read and process them.

For this reason, Yii provides the together query option so that we choose between the two approaches as needed. By default, Yii uses eager loading, i.e., generating a single SQL statement, except when LIMIT is applied to the primary model. We can set the together option in the relation declarations to be true to force a single SQL statement even when LIMIT is used. Setting it to false will result in some of tables will be joined in separate SQL statements. For example, in order to use separate SQL statements to query for the latest posts with their comments, we can declare the comments relation in Post class as follows,

<span>public</span> <span>function</span><span> relations()
{
    </span><span>return</span> <span>array</span><span>(
        </span>'comments' => <span>array</span>(self::HAS_MANY, 'Comment', 'post_id',
                        'together'=><span>false</span>),<span>
    );
}</span>
ログイン後にコピー

We can also dynamically set this option when we perform the eager loading:

<span>$posts</span> = Post::model()-><span>with(
            </span><span>array</span>('comments'=><span>array</span><span>(
                </span>'together'=><span>false</span><span>
            ))
        )</span>->findAll();
ログイン後にコピー

8. Statistical Query

Besides the relational query described above, Yii also supports the so-called statistical query (or aggregational query). It refers to retrieving the aggregational information about the related objects, such as the number of comments for each post, the average rating for each product, etc. Statistical query can only be performed for objects related in HAS_MANY (e.g. a post has many comments) or MANY_MANY (e.g. a post belongs to many categories and a category has many posts).

Performing statistical query is very similar to performing relation query as we described before. We first need to declare the statistical query in the relations() method of CActiveRecord like we do with relational query.

<span>class</span> Post <span>extends</span><span> CActiveRecord
{
    </span><span>public</span> <span>function</span><span> relations()
    {
        </span><span>return</span> <span>array</span><span>(
            </span>'commentCount'=><span>array</span>(self::<span>STAT</span>, 'Comment', 'post_id'),
            'categoryCount'=><span>array</span><span>(
                self</span>::<span>STAT</span>, 'Category', 'post_category(post_id, category_id)'<span>
            )</span>,<span>
        );
    }
}</span>
ログイン後にコピー

In the above, we declare two statistical queries: commentCount calculates the number of comments belonging to a post, and categoryCount calculates the number of categories that a post belongs to. Note that the relationship between Post and Comment is HAS_MANY, while the relationship between Post and Category isMANY_MANY (with the joining table post_category). As we can see, the declaration is very similar to those relations we described in earlier subsections. The only difference is that the relation type is STAT here.

With the above declaration, we can retrieve the number of comments for a post using the expression $post->commentCount. When we access this property for the first time, a SQL statement will be executed implicitly to retrieve the corresponding result. As we already know, this is the so-called lazy loading approach. We can also use the eager loading approach if we need to determine the comment count for multiple posts:

<span>$posts</span>=Post::model()->with('commentCount', 'categoryCount')->findAll();
ログイン後にコピー

The above statement will execute three SQLs to bring back all posts together with their comment counts and category counts. Using the lazy loading approach, we would end up with 2*N+1 SQL queries if there are Nposts.

By default, a statistical query will calculate the COUNT expression (and thus the comment count and category count in the above example). We can customize it by specifying additional options when we declare it inrelations(). The available options are summarized as below.

  • select: the statistical expression. Defaults to COUNT(*), meaning the count of child objects.

  • defaultValue: the value to be assigned to those records that do not receive a statistical query result. For example, if a post does not have any comments, its commentCount would receive this value. The default value for this option is 0.

  • condition: the WHERE clause. It defaults to empty.

  • params: the parameters to be bound to the generated SQL statement. This should be given as an array of name-value pairs.

  • order: the ORDER BY clause. It defaults to empty.

  • group: the GROUP BY clause. It defaults to empty.

  • having: the HAVING clause. It defaults to empty.

9. Relational Query with Named Scopes

Relational query can also be performed in combination with named scopes. It comes in two forms. In the first form, named scopes are applied to the main model. In the second form, named scopes are applied to the related models.

The following code shows how to apply named scopes to the main model.

<span>$posts</span>=Post::model()->published()->recently()->with('comments')->findAll();
ログイン後にコピー

This is very similar to non-relational queries. The only difference is that we have the with() call after the named-scope chain. This query would bring back recently published posts together with their comments.

And the following code shows how to apply named scopes to the related models.

<span>$posts</span>=Post::model()->with('comments:recently:approved')-><span>findAll();
</span><span>//</span><span> or since 1.1.7</span>
<span>$posts</span>=Post::model()->with(<span>array</span><span>(
    </span>'comments'=><span>array</span><span>(
        </span>'scopes'=><span>array</span>('recently','approved'<span>)
    )</span>,<span>
))</span>-><span>findAll();
</span><span>//</span><span> or since 1.1.7</span>
<span>$posts</span>=Post::model()->findAll(<span>array</span><span>(
    </span>'with'=><span>array</span><span>(
        </span>'comments'=><span>array</span><span>(
            </span>'scopes'=><span>array</span>('recently','approved'<span>)
        )</span>,<span>
    )</span>,<span>
));</span>
ログイン後にコピー

The above query will bring back all posts together with their approved comments. Note that comments refers to the relation name, while recently and approved refer to two named scopes declared in the Comment model class. The relation name and the named scopes should be separated by colons.

Occasionally you may need to retrieve a scoped relationship using a lazy-loading approach, instead of the normal eager loading method shown above. In that case, the following syntax will do what you need:

~~ [php] // note the repetition of the relationship name, which is necessary $approvedComments = $post->comments('comments:approved'); ~~

Named scopes can also be specified in the with option of the relational rules declared inCActiveRecord::relations(). In the following example, if we access $user->posts, it would bring back allapproved comments of the posts.

<span>class</span> User <span>extends</span><span> CActiveRecord
{
    </span><span>public</span> <span>function</span><span> relations()
    {
        </span><span>return</span> <span>array</span><span>(
            </span>'posts'=><span>array</span>(self::HAS_MANY, 'Post', 'author_id',
                'with'=>'comments:approved'),<span>
        );
    }
}
 
</span><span>//</span><span> or since 1.1.7</span>
<span>class</span> User <span>extends</span><span> CActiveRecord
{
    </span><span>public</span> <span>function</span><span> relations()
    {
        </span><span>return</span> <span>array</span><span>(
            </span>'posts'=><span>array</span>(self::HAS_MANY, 'Post', 'author_id',
                'with'=><span>array</span><span>(
                    </span>'comments'=><span>array</span><span>(
                        </span>'scopes'=>'approved'<span>
                    )</span>,<span>
                )</span>,<span>
            )</span>,<span>
        );
    }
}</span>
ログイン後にコピー

Note: Before 1.1.7 named scopes applied to related models must be specified in CActiveRecord::scopes. As a result, they cannot be parameterized.

Since 1.1.7 it's possible to pass parameters for relational named scopes. For example, if you have scope named rated in the Post that accepts minimum rating of post, you can use it from User the following way:

<span>$users</span>=User::model()->findAll(<span>array</span><span>(
    </span>'with'=><span>array</span><span>(
        </span>'posts'=><span>array</span><span>(
            </span>'scopes'=><span>array</span><span>(
                </span>'rated'=>5,<span>
            )</span>,<span>
        )</span>,<span>
    )</span>,<span>
));
 
</span><span>class</span> Post <span>extends</span><span> CActiveRecord
{
    </span>......
 
    <span>public</span> <span>function</span> rated(<span>$rating</span><span>)
    {
        </span><span>$this</span>->getDbCriteria()->mergeWith(<span>array</span><span>(
            </span>'condition'=>'rating=:rating',
            'params'=><span>array</span>(':rating'=><span>$rating</span>),<span>
        ));
        </span><span>return</span> <span>$this</span><span>;
    }
 
    </span>......<span>
}</span>
ログイン後にコピー

10. Relational Query with through

When using through, relation definition should look like the following:

'comments'=><span>array</span>(self::HAS_MANY,'Comment',<span>array</span>('key1'=>'key2'),'through'=>'posts'),
ログイン後にコピー

In the above array('key1'=>'key2'):

  • key1 is a key defined in relation specified in through (posts is this case).
  • key2 is a key defined in a model relation points to (Comment in this case).

through can be used with HAS_ONE, BELONGS_TO and HAS_MANY relations.

HAS_MANY through

HAS_MANY through ER

An example of HAS_MANY with through is getting users from a particular group when users are assigned to groups via roles.

A bit more complex example is getting all comments for all users of a particular group. In this case we have to use several relations with through in a single model:

<span>class</span> Group <span>extends</span><span> CActiveRecord
{
    </span>...
    <span>public</span> <span>function</span><span> relations()
    {
        </span><span>return</span> <span>array</span><span>(
            </span>'roles'=><span>array</span>(self::HAS_MANY,'Role','group_id'),
            'users'=><span>array</span><span>(
                self</span>::HAS_MANY,'User',<span>array</span>('user_id'=>'id'),'through'=>'roles'<span>
            )</span>,
            'comments'=><span>array</span><span>(
                self</span>::HAS_MANY,'Comment',<span>array</span>('id'=>'user_id'),'through'=>'users'<span>
            )</span>,<span>
        );
    }
}</span>
ログイン後にコピー

Usage examples

<span>//</span><span> get all groups with all corresponding users</span>
<span>$groups</span>=Group::model()->with('users')-><span>findAll();
 
</span><span>//</span><span> get all groups with all corresponding users and roles</span>
<span>$groups</span>=Group::model()->with('roles','users')-><span>findAll();
 
</span><span>//</span><span> get all users and roles where group ID is 1</span>
<span>$group</span>=Group::model()->findByPk(1<span>);
</span><span>$users</span>=<span>$group</span>-><span>users;
</span><span>$roles</span>=<span>$group</span>-><span>roles;
 
</span><span>//</span><span> get all comments where group ID is 1</span>
<span>$group</span>=Group::model()->findByPk(1<span>);
</span><span>$comments</span>=<span>$group</span>->comments;
ログイン後にコピー

HAS_ONE through

HAS_ONE through ER

An example of using HAS_ONE with through is getting user address where user is bound to address using profile. All these entities (user, profile, and address) do have corresponding models:

<span>class</span> User <span>extends</span><span> CActiveRecord
{
    </span>...
    <span>public</span> <span>function</span><span> relations()
    {
        </span><span>return</span> <span>array</span><span>(
            </span>'profile'=><span>array</span>(self::HAS_ONE,'Profile','user_id'),
            'address'=><span>array</span><span>(
                self</span>::HAS_ONE,'Address',<span>array</span>('id'=>'profile_id'),
                    'through'=>'profile'<span>
            )</span>,<span>
        );
    }
}</span>
ログイン後にコピー

Usage examples

<span>//</span><span> get address of a user whose ID is 1</span>
<span>$user</span>=User::model()->findByPk(1<span>);
</span><span>$address</span>=<span>$user</span>->address;
ログイン後にコピー

through on self

through can be used for a model bound to itself using a bridge model. In our case it's a user mentoring other users:

through self ER

That's how we can define relations for this case:

<span>class</span> User <span>extends</span><span> CActiveRecord
{
    </span>...
    <span>public</span> <span>function</span><span> relations()
    {
        </span><span>return</span> <span>array</span><span>(
            </span>'mentorships'=><span>array</span><span>(
                self</span>::HAS_MANY,'Mentorship','teacher_id','joinType'=>'INNER JOIN'<span>
            )</span>,
            'students'=><span>array</span><span>(
                self</span>::HAS_MANY,'User',<span>array</span>('student_id'=>'id'),
                    'through'=>'mentorships','joinType'=>'INNER JOIN'<span>
            )</span>,<span>
        );
    }
}</span>
ログイン後にコピー

Usage examples

<span>//</span><span> get all students taught by teacher whose ID is 1</span>
<span>$teacher</span>=User::model()->findByPk(1<span>);
</span><span>$students</span>=<span>$teacher</span>->students;
ログイン後にコピー

 

 

yii框架怎访问api

1. Yii

Yii は、大規模な Web アプリケーションを開発するための高性能コンポーネントベースの PHP フレームワークです。 Yii は厳密な OOP で書かれており、完全なライブラリ リファレンスと包括的なチュートリアルが含まれています。 MVC、DAO/ActiveRecord、ウィジェット、キャッシュ、階層型 RBAC、Web サービスからプリンシパル化、I18N および L10N まで、Yii は今日の Web 2.0 アプリケーション開発に必要なほぼすべてを提供します。そしてこのフレームの価格はそれほど高くありません。実際、Yii は最も効率的な PHP フレームワークの 1 つです。

2. CodeIgniter

CodeIgniter はアプリケーション開発フレームワークであり、PHP Web サイトを構築する人のために設計されたツールキットです。その目標は、プロジェクトを迅速に開発することです。一般的なタスクを完了するための豊富なライブラリ セットと、これらのライブラリにアクセスするためのシンプルなインターフェイスとよく整理された構造が提供されます。 CodeIgniter を使用して開発すると、コーディング時間を大幅に節約できるため、プロジェクトにより多くの創造性を注入できます。

3. CakePHP

CakePHP は、ActiveRecord、Association Data Mapping、フロント コントローラー、MVC などのいくつかの一般的な設計パターンを使用する、PHP の迅速な開発のためのフレームワークです。その主な目標は、あらゆるレベルの PHP 開発者が Web アプリケーションを迅速に開発できるフレームワークを提供することであり、この迅速な実装によってプロジェクトの柔軟性が犠牲になることはありません。

4. PHPDevShell

PHPDevShell は、JavaScript を使用せずに純粋な PHP を開発するためのオープンソース (GNU/LGPL) 高速アプリケーション開発フレームワークです。完全な GUI 管理者バックエンド インターフェイスを備えています。その主な目標は、速度、セキュリティ、安定性、柔軟性が最優先される、プラグインなどの管理ベースのアプリケーションを開発することです。学習が容易になるように設計されているため、PHP 開発者は複雑な新しい用語を学ぶ必要がありません。 PHPDevShell の登場により、軽量でありながら制限なく構成できる完全に機能する GUI に対する開発者のニーズが満たされます。

5. Akelos

Akelos PHP フレームワークは、MVC デザイン パターンに基づいた Web アプリケーション開発プラットフォームです。適切な使用習慣に基づいて、これを使用して次のタスクを実行できます:

◆Ajax を使用してビューを作成するのが便利

◆コントローラーを介してリクエストと応答を管理

◆国際的なアプリケーションを管理

◆使用方法モデルと通信するためのシンプルなプロトコルサーバー上の Akelos の唯一の要件は PHP をサポートすることであるため、Akelos アプリケーションはほとんどの共有ホスティングプロバイダーで実行できます。したがって、Akelos PHP フレームワークは、実行するために非標準の PHP 構成を必要としないため、スタンドアロン Web アプリケーションを公開するのに最適です。

6. Symfony

Symfony は、PHP5 プロジェクトを開発するための Web アプリケーション フレームワークです。

このフレームワークの目的は、Web アプリケーションの開発とメンテナンスを高速化し、反復的なコーディング作業を削減することです。

Symfony はシステム要件が低く、どのようなセットアップにも簡単にインストールできます。必要なのは、Unix または Windows と、PHP5 がインストールされた Web サーバーだけです。ほぼすべてのデータベースと互換性があります。 Symfony の価格はそれほど高くはなく、ホストのコストよりもはるかに低いです。

PHP 開発者にとって、Symfony を使用するのは自然なことであり、学習曲線はわずか 1 日です。すっきりとしたデザインとコードの読みやすさにより、開発時間が短縮されます。開発者は、アジャイル開発の原則 (DRY、KISS、XP など) を適用して、無限の XML 構成ファイルの作成に多くの時間を費やすことなく、アプリケーションのロジック レベルに集中できます。

Symfony は、エンタープライズレベルで完全なアプリケーションを構築するように設計されています。つまり、セットアップ全体を制御できます。パス構造から外部ライブラリに至るまで、ほぼすべてをカスタマイズできます。エンタープライズ開発規制に準拠するために、Symfony にはプロジェクトのテスト、デバッグ、アーカイブを容易にするいくつかの追加ツールもバンドルされています。

7. プラド

プラドチームはプラド愛好家で構成されています...続きは>>


今日、yii の学習を始めました。午前中ずっとガイドを読んでも何も見つかりませんでした。もっとポイントを獲得できるように、ベテランからのアドバイスが欲しいです。 キーワードをいくつか挙げておきます

1.MVC

2.イベントドリブン
3.ActiveRecord
4.コンポーネント指向
これらを手放さず、よく見てください





http://www.bkjia.com/PHPjc/867006.html

www.bkjia.com

tru​​e

http://www.bkjia.com/PHPjc/867006.html技術記事 Yii学習(5)--Active Record association、yii--active 公式サイト原文: http://www.yiiframework.com/doc/guide/1.1/zh_cn/database.arr 公式サイトの後半は英語と中国語のコンテンツの方が優れています...
関連ラベル:
yii
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!