程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> Yii的學習(5)--Active Record的關聯,yii--active

Yii的學習(5)--Active Record的關聯,yii--active

編輯:關於PHP編程

Yii的學習(5)--Active Record的關聯,yii--active


官網原文:http://www.yiiframework.com/doc/guide/1.1/zh_cn/database.arr

官網中後半段為英文,而且中文的內容比英文少一些,先放到這裡,之後有時間再翻譯。

我們已經了解了怎樣使用 Active Record (AR) 從單個數據表中獲取數據。 在本節中,我們講解怎樣使用 AR 連接多個相關數據表並取回關聯(join)後的數據集。

為了使用關系型 AR,我們建議在需要關聯的表中定義主鍵-外鍵約束。這些約束可以幫助保證相關數據的一致性和完整性。

為簡單起見,我們使用如下所示的實體-關系(ER)圖中的數據結構演示此節中的例子。

信息: 對外鍵約束的支持在不同的 DBMS 中是不一樣的。 SQLite < 3.6.19 不支持外鍵約束,但你依然可以在建表時聲明約束。

1. 聲明關系 

在我們使用 AR 執行關聯查詢之前,我們需要讓 AR 知道一個 AR 類是怎樣關聯到另一個的。

兩個 AR 類之間的關系直接通過 AR 類所代表的數據表之間的關系相關聯。 從數據庫的角度來說,表 A 和 B 之間有三種關系:一對多(one-to-many,例如 tbl_user 和 tbl_post),一對一( one-to-one 例如 tbl_user 和tbl_profile)和 多對多(many-to-many 例如 tbl_category 和 tbl_post)。 在 AR 中,有四種關系:

  • 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 中的 relations() 方法。此方法返回一個關系配置數組。每個數組元素通過如下格式表示一個單一的關系。

'VarName'=>array('RelationType', 'ClassName', 'ForeignKey', ...additional options)

其中 VarName 是關系的名字;RelationType 指定關系類型,可以是一下四個常量之一: self::BELONGS_TO,self::HAS_ONEself::HAS_MANY and self::MANY_MANYClassName 是此 AR 類所關聯的 AR 類的名字;ForeignKey 指定關系中使用的外鍵(一個或多個)。額外的選項可以在每個關系的最後指定(稍後詳述)。

以下代碼演示了怎樣定義 User 和 Post 類的關系:

class Post extends CActiveRecord
{
    ......
 
    public function relations()
    {
        return array(
            'author'=>array(self::BELONGS_TO, 'User', 'author_id'),
            'categories'=>array(self::MANY_MANY, 'Category',
                'tbl_post_category(post_id, category_id)'),
        );
    }
}
 
class User extends CActiveRecord
{
    ......
 
    public function relations()
    {
        return array(
            'posts'=>array(self::HAS_MANY, 'Post', 'author_id'),
            'profile'=>array(self::HAS_ONE, 'Profile', 'owner_id'),
        );
    }
}

信息: 外鍵可能是復合的,包含兩個或更多個列。 這種情況下,我們應該將這些外鍵名字鏈接,中間用空格或逗號分割。對於 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,也可譯為 遲加載) 方式,例如,關聯查詢只在關聯的對象首次被訪問時執行。 下面的例子演示了怎樣使用這種方式:

// 獲取 ID 為 10 的帖子
$post=Post::model()->findByPk(10);
// 獲取帖子的作者(author): 此處將執行一個關聯查詢。
$author=$post->author;

信息: 如果關系中沒有相關的實例,則相應的屬性將為 null 或一個空數組。 BELONGS_TO 和 HAS_ONE關系的結果是 null, HAS_MANY 和 MANY_MANY 的結果是一個空數組。 注意, HAS_MANY 和MANY_MANY 關系返回對象數組,你需要在訪問任何屬性之前先遍歷這些結果。 否則,你可能會收到 "Trying to get property of non-object(嘗試訪問非對象的屬性)" 錯誤。

懶惰式加載用起來很方便,但在某些情況下並不高效。如果我們想獲取 N 個帖子的作者,使用這種懶惰式加載將會導致執行 N 個關聯查詢。 這種情況下,我們應該改為使用 渴求式加載(eager loading)方式。

渴求式加載方式會在獲取主 AR 實例的同時獲取關聯的 AR 實例。 這是通過在使用 AR 中的 find 或 findAll 方法時配合使用 with 方法完成的。例如:

$posts=Post::model()->with('author')->findAll();

上述代碼將返回一個 Post 實例的數組。與懶惰式加載方式不同,在我們訪問每個 Post 實例中的 author 屬性之前,它就已經被關聯的 User 實例填充了。 渴求式加載通過 一個 關聯查詢返回所有帖子及其作者,而不是對每個帖子執行一次關聯查詢。

我們可以在 with() 方法中指定多個關系名字,渴求式加載將一次性全部取回他們。例如,如下代碼會將帖子連同其作者和分類一並取回。

$posts=Post::model()->with('author','categories')->findAll();

我們也可以實現嵌套的渴求式加載。像下面這樣, 我們傳遞一個分等級的關系名表達式到 with() 方法,而不是一個關系名列表:

$posts=Post::model()->with(
    'author.profile',
    'author.posts',
    'categories')->findAll();

上述示例將取回所有帖子及其作者和所屬分類。它還同時取回每個作者的簡介(author.profile)和帖子(author.posts)。

從版本 1.1.0 開始,渴求式加載也可以通過指定 CDbCriteria::with 的屬性執行,就像下面這樣:

$criteria=new CDbCriteria;
$criteria->with=array(
    'author.profile',
    'author.posts',
    'categories',
);
$posts=Post::model()->findAll($criteria);

或者

$posts=Post::model()->findAll(array(
    'with'=>array(
        'author.profile',
        'author.posts',
        'categories',
    )
);

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:

class User extends CActiveRecord
{
    public function relations()
    {
        return array(
            'posts'=>array(self::HAS_MANY, 'Post', 'author_id',
                            'order'=>'posts.create_time DESC',
                            'with'=>'categories'),
            'profile'=>array(self::HAS_ONE, 'Profile', 'owner_id'),
        );
    }
}

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:

$posts=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:

$posts=Post::model()->with('comments')->findAll(array(
    'order'=>'t.create_time, comments.create_time'
));

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'.

$posts=Post::model()->with('author', 'author.group')->findAll(array(
  'order'=>'group.name, author.name, t.title'
));

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

$comments=Comment::model()->with(
  'author',
  'post',
  'post.author'=>array('alias'=>'p_author'))->findAll(array(
  'order'=>'author.name, p_author.name, post.title'
));

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(array(
    'posts'=>array('order'=>'posts.create_time ASC'),
    'profile',
))->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:

$user=User::model()->findByPk(1);
$posts=$user->posts(array('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,

public function relations()
{
    return array(
        'comments' => array(self::HAS_MANY, 'Comment', 'post_id',
                        'together'=>false),
    );
}

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

$posts = Post::model()->with(
            array('comments'=>array(
                'together'=>false
            ))
        )->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.

class Post extends CActiveRecord
{
    public function relations()
    {
        return array(
            'commentCount'=>array(self::STAT, 'Comment', 'post_id'),
            'categoryCount'=>array(
                self::STAT, 'Category', 'post_category(post_id, category_id)'
            ),
        );
    }
}

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:

$posts=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.

$posts=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.

$posts=Post::model()->with('comments:recently:approved')->findAll();
// or since 1.1.7
$posts=Post::model()->with(array(
    'comments'=>array(
        'scopes'=>array('recently','approved')
    ),
))->findAll();
// or since 1.1.7
$posts=Post::model()->findAll(array(
    'with'=>array(
        'comments'=>array(
            'scopes'=>array('recently','approved')
        ),
    ),
));

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.

class User extends CActiveRecord
{
    public function relations()
    {
        return array(
            'posts'=>array(self::HAS_MANY, 'Post', 'author_id',
                'with'=>'comments:approved'),
        );
    }
}
 
// or since 1.1.7
class User extends CActiveRecord
{
    public function relations()
    {
        return array(
            'posts'=>array(self::HAS_MANY, 'Post', 'author_id',
                'with'=>array(
                    'comments'=>array(
                        'scopes'=>'approved'
                    ),
                ),
            ),
        );
    }
}

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:

$users=User::model()->findAll(array(
    'with'=>array(
        'posts'=>array(
            'scopes'=>array(
                'rated'=>5,
            ),
        ),
    ),
));
 
class Post extends CActiveRecord
{
    ......
 
    public function rated($rating)
    {
        $this->getDbCriteria()->mergeWith(array(
            'condition'=>'rating=:rating',
            'params'=>array(':rating'=>$rating),
        ));
        return $this;
    }
 
    ......
}

10. Relational Query with through 

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

'comments'=>array(self::HAS_MANY,'Comment',array('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_ONEBELONGS_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:

class Group extends CActiveRecord
{
    ...
    public function relations()
    {
        return array(
            'roles'=>array(self::HAS_MANY,'Role','group_id'),
            'users'=>array(
                self::HAS_MANY,'User',array('user_id'=>'id'),'through'=>'roles'
            ),
            'comments'=>array(
                self::HAS_MANY,'Comment',array('id'=>'user_id'),'through'=>'users'
            ),
        );
    }
}

Usage examples

// get all groups with all corresponding users
$groups=Group::model()->with('users')->findAll();
 
// get all groups with all corresponding users and roles
$groups=Group::model()->with('roles','users')->findAll();
 
// get all users and roles where group ID is 1
$group=Group::model()->findByPk(1);
$users=$group->users;
$roles=$group->roles;
 
// get all comments where group ID is 1
$group=Group::model()->findByPk(1);
$comments=$group->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:

class User extends CActiveRecord
{
    ...
    public function relations()
    {
        return array(
            'profile'=>array(self::HAS_ONE,'Profile','user_id'),
            'address'=>array(
                self::HAS_ONE,'Address',array('id'=>'profile_id'),
                    'through'=>'profile'
            ),
        );
    }
}

Usage examples

// get address of a user whose ID is 1
$user=User::model()->findByPk(1);
$address=$user->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:

class User extends CActiveRecord
{
    ...
    public function relations()
    {
        return array(
            'mentorships'=>array(
                self::HAS_MANY,'Mentorship','teacher_id','joinType'=>'INNER JOIN'
            ),
            'students'=>array(
                self::HAS_MANY,'User',array('student_id'=>'id'),
                    'through'=>'mentorships','joinType'=>'INNER JOIN'
            ),
        );
    }
}

Usage examples

// get all students taught by teacher whose ID is 1
$teacher=User::model()->findByPk(1);
$students=$teacher->students;

 

 


yii框架怎訪問api

1. Yii

Yii是一個基於組件的高性能的PHP的框架,用於開發大規模Web應用。Yii采用嚴格的OOP編寫,並有著完善的庫引用以及全面的教程。從MVC,DAO/ActiveRecord,widgets,caching,等級式RBAC,Web服務,到主體化,I18N和L10N,Yii提供了今日Web 2.0應用開發所需要的幾乎一切功能。而且這個框架的價格也並不太高。事實上,Yii是最有效率的PHP框架之一。

2. CodeIgniter

CodeIgniter是一個應用開發框架——一個為建立PHP網站的人們所設計的工具包。其目標在於快速的開發項目:它提供了豐富的庫組以完成常見的任務,以及簡單的界面,富有條理性的架構來訪問這些庫。使用CodeIgniter開發可以往項目中注入更多的創造力,因為它節省了大量編碼的時間。

3. CakePHP

CakePHP是一個快速開發PHP的框架,其中使用了一些常見的設計模式如ActiveRecord,Association Data Mapping,Front Controller以及MVC。其主要目標在於提供一個令任意水平的PHP開發人員都能夠快速開發web應用的框架,而且這個快速的實現並沒有犧牲項目的彈性。

4. PHPDevShell

PHPDevShell是一個開源(GNU/LGPL)的快速應用開發框架,用於開發不含Javascript的純PHP。它有一個完整的GUI管理員後台界面。其主要目標在於開發插件一類的基於管理的應用,其中速度、安全、穩定性及彈性是最優先考慮的重點。其設計形成了一個簡單的學習曲線,PHP開發者無需學習復雜的新術語。PHPDevShell的到來滿足了開發者們對於一個輕量級但是功能完善,可以無限制的進行配置的GUI的需求。

5. Akelos

Akelos PHP框架是一個基於MVC設計模式的web應用開發平台。基於良好的使用習慣,使用它可以完成如下任務:

◆方便的使用Ajax編寫views

◆通過控制器管理請求(request)及響應(response)

◆管理國際化的應用

◆使用簡單的協議與模型及數據庫通信

你的Akelos應用可以在大多數共享主機服務供應方上運行,因為Akelos對服務器唯一的要求就是支持PHP。因此,Akelos PHP框架是理想的用於發布單獨web應用的框架,因為它不需要非標准PHP配置便能運行。

6. Symfony

Symfony是一個用於開發PHP5項目的web應用框架。

這個框架的目的在於加速web應用的開發以及維護,減少重復的編碼工作。

Symfony的系統需求不高,可以被輕易的安裝在任意設置上:你只需一個Unix或Windows,搭配一個安裝了PHP5的網絡服務器即可。它與差不多所有的數據庫兼容。Symfony的價位不高,相比主機上的花銷要低得多。

對於PHP開發者而言,使用Symfony是一件很自然的事,其學習曲線只有短短一天。干淨的設計以及代碼可讀性將縮短開發時間。開發者可以將敏捷開發的原理(如DRY,KISS或XP等)應用在其中,將重點放在應用邏輯層面上,而不用花費大量時間在編寫沒完沒了的XML配置文件上。

Symfony旨在建立企業級的完善應用程序。也就是說,你擁有整個設置的控制權:從路徑結構到外部庫,幾乎一切都可以自定義。為了符合企業的開發條例,Symfony還綁定了一些額外的工具,以便於項目的測試,調試以及歸檔。

7. Prado

PRADO團隊由一些PRADO狂熱者......余下全文>>
 

今天開始學yii 看了一上午的guide 一無所獲,老鳥們給點建議,使勁加分

給你幾個關鍵字吧
1.MVC
2.事件驅動
3.ActiveRecord
4.面向組件
碰到這些不要放過,要仔細看
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved