From 97992bdc89ecec7f742835d0184f521aac4c91ac Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 4 May 2013 08:03:40 -0400 Subject: [PATCH 01/24] Fixes for issue #81. --- framework/YiiBase.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/framework/YiiBase.php b/framework/YiiBase.php index 9d501b1..ed975c9 100644 --- a/framework/YiiBase.php +++ b/framework/YiiBase.php @@ -600,6 +600,13 @@ class YiiBase */ public static function t($message, $params = array(), $language = null) { - return self::$app->getI18N()->translate($message, $params, $language); + if (self::$app !== null) { + return self::$app->getI18N()->translate($message, $params, $language); + } else { + if (strpos($message, '|') !== false && preg_match('/^([\w\-\\/\.\\\\]+)\|(.*)/', $message, $matches)) { + $message = $matches[2]; + } + return is_array($params) ? strtr($message, $params) : $message; + } } } From 0454d03177ce7acf431a1b279a75f3db29b97561 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 4 May 2013 08:08:46 -0400 Subject: [PATCH 02/24] Fixed test break. --- framework/helpers/base/Html.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/framework/helpers/base/Html.php b/framework/helpers/base/Html.php index 5b8e7db..3e7c7a2 100644 --- a/framework/helpers/base/Html.php +++ b/framework/helpers/base/Html.php @@ -95,9 +95,9 @@ class Html public static $attributeOrder = array( 'type', 'id', + 'class', 'name', 'value', - 'class', 'href', 'src', @@ -375,7 +375,8 @@ class Html */ public static function mailto($text, $email = null, $options = array()) { - return static::a($text, 'mailto:' . ($email === null ? $text : $email), $options); + $options['href'] = 'mailto:' . ($email === null ? $text : $email); + return static::tag('a', $text, $options); } /** From 2da3cbecdfb9ec5044f4f8e184a57b9bb8919276 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 4 May 2013 09:23:43 -0300 Subject: [PATCH 03/24] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index dfb9c45..6293292 100644 --- a/readme.md +++ b/readme.md @@ -34,6 +34,6 @@ You are welcome to participate in Yii 2 development in the following ways: * [Report issues](https://github.com/yiisoft/yii2/issues) * [Give us feedback or start a design discussion](http://www.yiiframework.com/forum/index.php/forum/42-design-discussions-for-yii-20/) * Fix issues, develop features, write/polish documentation - - Before you start, please adopt an existing issue or start a new one to avoid duplicated efforts. + - Before you start, please adopt an existing issue (labelled with "ready for adoption") or start a new one to avoid duplicated efforts. - Please submit a merge request after you finish development. From 2bdfc27692731da995f61bef103681b5c0aca184 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 4 May 2013 08:28:27 -0400 Subject: [PATCH 04/24] Fixes for issue #78. --- framework/helpers/base/Html.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/framework/helpers/base/Html.php b/framework/helpers/base/Html.php index 3e7c7a2..15db823 100644 --- a/framework/helpers/base/Html.php +++ b/framework/helpers/base/Html.php @@ -127,13 +127,15 @@ class Html * Encodes special characters into HTML entities. * The [[yii\base\Application::charset|application charset]] will be used for encoding. * @param string $content the content to be encoded + * @param boolean $doubleEncode whether to encode HTML entities in `$content`. If false, + * HTML entities in `$content` will not be further encoded. * @return string the encoded content * @see decode * @see http://www.php.net/manual/en/function.htmlspecialchars.php */ - public static function encode($content) + public static function encode($content, $doubleEncode = true) { - return htmlspecialchars($content, ENT_QUOTES, Yii::$app->charset); + return htmlspecialchars($content, ENT_QUOTES, Yii::$app->charset, $doubleEncode); } /** From 992992b4a3f3912119a54aa542a2946cf3ee3843 Mon Sep 17 00:00:00 2001 From: Suralc Date: Sat, 4 May 2013 15:55:01 +0200 Subject: [PATCH 05/24] Fix build command. --- build/build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build b/build/build index fff4282..691eba9 100755 --- a/build/build +++ b/build/build @@ -16,5 +16,5 @@ require(__DIR__ . '/../framework/yii.php'); $id = 'yiic-build'; $basePath = __DIR__; -$application = new yii\console\Application($id, $basePath); +$application = new yii\console\Application(array('id' => $id, 'basePath' => $basePath)); $application->run(); From 985f076b2db578bd44c896a1d80faa3a772d6761 Mon Sep 17 00:00:00 2001 From: Taufan Aditya Date: Sat, 4 May 2013 21:47:01 +0700 Subject: [PATCH 06/24] Testsuite config --- phpunit.xml.dist | 13 +++++++++++++ tests/unit/phpunit.xml | 7 ------- 2 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 phpunit.xml.dist delete mode 100644 tests/unit/phpunit.xml diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..bf37a26 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,13 @@ + + + + + ./tests/unit + + + \ No newline at end of file diff --git a/tests/unit/phpunit.xml b/tests/unit/phpunit.xml deleted file mode 100644 index 17db94e..0000000 --- a/tests/unit/phpunit.xml +++ /dev/null @@ -1,7 +0,0 @@ - - \ No newline at end of file From 305028b5c81463b977493de208167d87c28f47c0 Mon Sep 17 00:00:00 2001 From: Taufan Aditya Date: Sun, 5 May 2013 00:09:12 +0700 Subject: [PATCH 07/24] Travis configuration --- .travis.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..e4b8278 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +language: php + +php: + - 5.3 + - 5.4 + - 5.5 + +env: + - DB=mysql + +before_script: + - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS yiitest;'; fi" + +script: phpunit \ No newline at end of file From 51de7571401fea3ca272f5862cfb12e4dc0774a4 Mon Sep 17 00:00:00 2001 From: Taufan Aditya Date: Sun, 5 May 2013 00:10:17 +0700 Subject: [PATCH 08/24] Use travis as user instead root within DSN --- tests/unit/data/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/data/config.php b/tests/unit/data/config.php index fc15690..238a7cc 100644 --- a/tests/unit/data/config.php +++ b/tests/unit/data/config.php @@ -3,7 +3,7 @@ return array( 'mysql' => array( 'dsn' => 'mysql:host=127.0.0.1;dbname=yiitest', - 'username' => 'root', + 'username' => 'travis', 'password' => '', 'fixture' => __DIR__ . '/mysql.sql', ), From 88bfce96d43b5c067ea8a0c6fed3f103320f534d Mon Sep 17 00:00:00 2001 From: ekerazha Date: Sat, 4 May 2013 21:15:24 +0300 Subject: [PATCH 09/24] Use AES-192 for encryption --- framework/helpers/base/SecurityHelper.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/framework/helpers/base/SecurityHelper.php b/framework/helpers/base/SecurityHelper.php index 6ba48ba..e2f2215 100644 --- a/framework/helpers/base/SecurityHelper.php +++ b/framework/helpers/base/SecurityHelper.php @@ -42,7 +42,8 @@ class SecurityHelper public static function encrypt($data, $key) { $module = static::openCryptModule(); - $key = StringHelper::substr($key, 0, mcrypt_enc_get_key_size($module)); + // 192-bit (24 bytes) key size + $key = StringHelper::substr($key, 0, 24); srand(); $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($module), MCRYPT_RAND); mcrypt_generic_init($module, $key, $iv); @@ -63,7 +64,8 @@ class SecurityHelper public static function decrypt($data, $key) { $module = static::openCryptModule(); - $key = StringHelper::substr($key, 0, mcrypt_enc_get_key_size($module)); + // 192-bit (24 bytes) key size + $key = StringHelper::substr($key, 0, 24); $ivSize = mcrypt_enc_get_iv_size($module); $iv = StringHelper::substr($data, 0, $ivSize); mcrypt_generic_init($module, $key, $iv); @@ -148,7 +150,8 @@ class SecurityHelper if (!extension_loaded('mcrypt')) { throw new InvalidConfigException('The mcrypt PHP extension is not installed.'); } - $module = @mcrypt_module_open('rijndael-256', '', MCRYPT_MODE_CBC, ''); + // AES uses a 128-bit block size + $module = @mcrypt_module_open('rijndael-128', '', MCRYPT_MODE_CBC, ''); if ($module === false) { throw new Exception('Failed to initialize the mcrypt module.'); } @@ -269,4 +272,4 @@ class SecurityHelper $salt .= str_replace('+', '.', substr(base64_encode($rand), 0, 22)); return $salt; } -} \ No newline at end of file +} From 3b12bbd8f22196ff5ee894d5b12088f787b93602 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 4 May 2013 14:28:09 -0400 Subject: [PATCH 10/24] Fixes issue #90 --- framework/base/Widget.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/framework/base/Widget.php b/framework/base/Widget.php index 13e6d30..1aabd4f 100644 --- a/framework/base/Widget.php +++ b/framework/base/Widget.php @@ -83,7 +83,8 @@ class Widget extends Component */ public function render($view, $params = array()) { - return $this->view->render($view, $params, $this); + $viewFile = $this->findViewFile($view); + return $this->view->renderFile($viewFile, $params, $this); } /** From 14781584f9bacdff21ee03ec14dbb8c9bcf79e96 Mon Sep 17 00:00:00 2001 From: ekerazha Date: Sat, 4 May 2013 22:02:39 +0300 Subject: [PATCH 11/24] Use a string for the mode too The cipher is already specified as string --- framework/helpers/base/SecurityHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/helpers/base/SecurityHelper.php b/framework/helpers/base/SecurityHelper.php index e2f2215..ed5bfd6 100644 --- a/framework/helpers/base/SecurityHelper.php +++ b/framework/helpers/base/SecurityHelper.php @@ -151,7 +151,7 @@ class SecurityHelper throw new InvalidConfigException('The mcrypt PHP extension is not installed.'); } // AES uses a 128-bit block size - $module = @mcrypt_module_open('rijndael-128', '', MCRYPT_MODE_CBC, ''); + $module = @mcrypt_module_open('rijndael-128', '', 'cbc', ''); if ($module === false) { throw new Exception('Failed to initialize the mcrypt module.'); } From d8beaa648e5ec8e1aa7fe14513b47ba1ea2fb897 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sat, 4 May 2013 23:23:29 +0400 Subject: [PATCH 12/24] added doc files --- docs/guide/active-record.md | 0 docs/guide/authentication.md | 0 docs/guide/authorization.md | 0 docs/guide/caching.md | 3 +++ docs/guide/console.md | 0 docs/guide/dao.md | 0 docs/guide/error.md | 3 +++ docs/guide/extension.md | 0 docs/guide/form.md | 0 docs/guide/gii.md | 0 docs/guide/i18n.md | 0 docs/guide/installation.md | 11 ++++++----- docs/guide/logging.md | 0 docs/guide/migration.md | 3 +++ docs/guide/mvc.md | 3 ++- docs/guide/performance.md | 0 docs/guide/query-builder.md | 0 docs/guide/security.md | 0 docs/guide/template.md | 0 docs/guide/testing.md | 0 docs/guide/theming.md | 0 docs/guide/upgrade.md | 0 docs/guide/url.md | 3 +++ docs/guide/validation.md | 0 24 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 docs/guide/active-record.md create mode 100644 docs/guide/authentication.md create mode 100644 docs/guide/authorization.md create mode 100644 docs/guide/caching.md create mode 100644 docs/guide/console.md create mode 100644 docs/guide/dao.md create mode 100644 docs/guide/error.md create mode 100644 docs/guide/extension.md create mode 100644 docs/guide/form.md create mode 100644 docs/guide/gii.md create mode 100644 docs/guide/i18n.md create mode 100644 docs/guide/logging.md create mode 100644 docs/guide/migration.md create mode 100644 docs/guide/performance.md create mode 100644 docs/guide/query-builder.md create mode 100644 docs/guide/security.md create mode 100644 docs/guide/template.md create mode 100644 docs/guide/testing.md create mode 100644 docs/guide/theming.md create mode 100644 docs/guide/upgrade.md create mode 100644 docs/guide/url.md create mode 100644 docs/guide/validation.md diff --git a/docs/guide/active-record.md b/docs/guide/active-record.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/authentication.md b/docs/guide/authentication.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/authorization.md b/docs/guide/authorization.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/caching.md b/docs/guide/caching.md new file mode 100644 index 0000000..cd945e7 --- /dev/null +++ b/docs/guide/caching.md @@ -0,0 +1,3 @@ +Caching +======= + diff --git a/docs/guide/console.md b/docs/guide/console.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/dao.md b/docs/guide/dao.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/error.md b/docs/guide/error.md new file mode 100644 index 0000000..c97fada --- /dev/null +++ b/docs/guide/error.md @@ -0,0 +1,3 @@ +Error Handling +============== + diff --git a/docs/guide/extension.md b/docs/guide/extension.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/form.md b/docs/guide/form.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/gii.md b/docs/guide/gii.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/i18n.md b/docs/guide/i18n.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/installation.md b/docs/guide/installation.md index 6cc5ef8..3f9a803 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -25,8 +25,8 @@ http://hostname/path/to/yii/requirements/index.php ~~~ Yii requires PHP 5.3, so the server must have PHP 5.3 or above installed and -available to the web server. Yii has been tested with [Apache HTTP server](http://httpd.apache.org/) -on Windows and Linux. It may also run on other Web servers and platforms, +available to the web server. Yii has been tested with [Apache HTTP server](http://httpd.apache.org/) +on Windows and Linux. It may also run on other Web servers and platforms, provided PHP 5.3 is supported. @@ -34,7 +34,7 @@ Recommended Apache Configuration -------------------------------- Yii is ready to work with a default Apache web server configuration. -The `.htaccess` files in Yii framework and application folders restrict +The `.htaccess` files in Yii framework and application folders deny access to the restricted resources. To hide the bootstrap file (usually `index.php`) in your URLs you can add `mod_rewrite` instructions to the `.htaccess` file in your document root or to the virtual host configuration: @@ -63,7 +63,7 @@ server { access_log /www/mysite/log/access.log main; server_name mysite; - root $host_path/htdocs; + root $host_path/htdocs; set $yii_bootstrap "index.php"; charset utf-8; @@ -108,4 +108,5 @@ server { } ~~~ -Using this configuration you can set `cgi.fix_pathinfo=0` in php.ini to avoid many unnecessary system stat() calls. +Using this configuration you can set `cgi.fix_pathinfo=0` in php.ini to avoid +many unnecessary system `stat()` calls. diff --git a/docs/guide/logging.md b/docs/guide/logging.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/migration.md b/docs/guide/migration.md new file mode 100644 index 0000000..0fe2fb3 --- /dev/null +++ b/docs/guide/migration.md @@ -0,0 +1,3 @@ +Database Migration +================== + diff --git a/docs/guide/mvc.md b/docs/guide/mvc.md index 79140ce..a99d043 100644 --- a/docs/guide/mvc.md +++ b/docs/guide/mvc.md @@ -11,7 +11,7 @@ the communication between the model and the view. Besides implementing MVC, Yii also introduces a front-controller, called `Application`, which encapsulates the execution context for the processing -of a request. Application collects some information about a user request and +of a request. Application collects information about a user request and then dispatches it to an appropriate controller for further handling. The following diagram shows the static structure of a Yii application: @@ -21,6 +21,7 @@ The following diagram shows the static structure of a Yii application: A Typical Workflow ------------------ + The following diagram shows a typical workflow of a Yii application when it is handling a user request: diff --git a/docs/guide/performance.md b/docs/guide/performance.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/query-builder.md b/docs/guide/query-builder.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/security.md b/docs/guide/security.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/template.md b/docs/guide/template.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/testing.md b/docs/guide/testing.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/theming.md b/docs/guide/theming.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/upgrade.md b/docs/guide/upgrade.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/url.md b/docs/guide/url.md new file mode 100644 index 0000000..46bb177 --- /dev/null +++ b/docs/guide/url.md @@ -0,0 +1,3 @@ +URL Management +============== + diff --git a/docs/guide/validation.md b/docs/guide/validation.md new file mode 100644 index 0000000..e69de29 From 1a317ebe313252c08fcbf3f89388b06414975d0f Mon Sep 17 00:00:00 2001 From: Rinat Silnov Date: Sat, 4 May 2013 23:54:59 +0400 Subject: [PATCH 13/24] Fixed VarDumper::dump for objects Otherwise it throws an exception that "Object of class ClassName could not be converted to string" --- framework/helpers/base/VarDumper.php | 2 +- tests/unit/framework/helpers/VarDumperTest.php | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 tests/unit/framework/helpers/VarDumperTest.php diff --git a/framework/helpers/base/VarDumper.php b/framework/helpers/base/VarDumper.php index fe15d98..43b0cd8 100644 --- a/framework/helpers/base/VarDumper.php +++ b/framework/helpers/base/VarDumper.php @@ -116,7 +116,7 @@ class VarDumper } elseif (self::$_depth <= $level) { self::$_output .= get_class($var) . '(...)'; } else { - $id = self::$_objects[] = $var; + $id = array_push(self::$_objects, $var); $className = get_class($var); $members = (array)$var; $spaces = str_repeat(' ', $level * 4); diff --git a/tests/unit/framework/helpers/VarDumperTest.php b/tests/unit/framework/helpers/VarDumperTest.php new file mode 100644 index 0000000..8757588 --- /dev/null +++ b/tests/unit/framework/helpers/VarDumperTest.php @@ -0,0 +1,12 @@ + Date: Sun, 5 May 2013 00:02:14 +0400 Subject: [PATCH 14/24] started performance section of the guide --- docs/guide/performance.md | 100 ++++++++++++++++++++++++++++++++++++++++++++++ docs/guide/template.md | 3 ++ 2 files changed, 103 insertions(+) diff --git a/docs/guide/performance.md b/docs/guide/performance.md index e69de29..a480a0b 100644 --- a/docs/guide/performance.md +++ b/docs/guide/performance.md @@ -0,0 +1,100 @@ +Performance Tuning +================== + +Application performance consists of two parts. First is the framework performance +and the second is the application itself. Yii has a pretty low performance impact +on your application out of the box and can be fine-tuned further for production +environment. As for the application, we'll provide some of the best practices +along with examples on how to apply them to Yii. + +Preparing framework for production +---------------------------------- + +### Disabling Debug Mode + +First thing you should do before deploying your application to production environment +is to disable debug mode. A Yii application runs in debug mode if the constant +`YII_DEBUG` is defined as `true` in `index.php`. Debug mode is useful during +development stage, but it would impact performance because some components +cause extra burden in debug mode. For example, the message logger may record +additional debug information for every message being logged. + +### Enabling PHP opcode cache + +Enabling the PHP opcode cache improves any PHP application performance and lowers +memory usage. Yii is no exception. It was tested with APC extension that caches +and optimizes PHP intermediate code and avoids the time spent in parsing PHP +scripts for every incoming request. + +### Turning on ActiveRecord database schema caching + +If the application is using Active Record, we should turn on the schema caching +to save the time of parsing database schema. This can be done by setting the +`Connection::enableSchemaCache` property to be `true` via application configuration +`protected/config/main.php`: + +```php + +``` + +### Combining and Minimizing Assets + + +### Using better storage for sessions + +By default PHP uses plain files to handle sessions. It is OK for development and +small projects but when it comes to handling concurrent requests it's better to +switch to another storage such as database. You can do so by configuring your +application via `protected/config/main.php`: + + +```php +``` + + +Improving application +--------------------- + +### Using Caching Techniques + +As described in the Caching section, Yii provides several caching solutions that +may improve the performance of a Web application significantly. If the generation +of some data takes long time, we can use the data caching approach to reduce the +data generation frequency; If a portion of page remains relatively static, we +can use the fragment caching approach to reduce its rendering frequency; +If a whole page remains relative static, we can use the page caching approach to +save the rendering cost for the whole page. + + +### Database Optimization + +Fetching data from database is often the main performance bottleneck in +a Web application. Although using caching may alleviate the performance hit, +it does not fully solve the problem. When the database contains enormous data +and the cached data is invalid, fetching the latest data could be prohibitively +expensive without proper database and query design. + +Design index wisely in a database. Indexing can make SELECT queries much faster, +but it may slow down INSERT, UPDATE or DELETE queries. + +For complex queries, it is recommended to create a database view for it instead +of issuing the queries inside the PHP code and asking DBMS to parse them repetitively. + +Do not overuse Active Record. Although Active Record is good at modelling data +in an OOP fashion, it actually degrades performance due to the fact that it needs +to create one or several objects to represent each row of query result. For data +intensive applications, using DAO or database APIs at lower level could be +a better choice. + +Last but not least, use LIMIT in your SELECT queries. This avoids fetching +overwhelming data from database and exhausting the memory allocated to PHP. + +### Using asArray + +### Processing data in background + +In order to respond to user requests faster you can process heavy parts of the +request later if there's no need for immediate response. + +- Cron jobs + console. +- queues + handlers. \ No newline at end of file diff --git a/docs/guide/template.md b/docs/guide/template.md index e69de29..dc83d15 100644 --- a/docs/guide/template.md +++ b/docs/guide/template.md @@ -0,0 +1,3 @@ +Template +======== + From 958aeb76b6c866615a2f428b3c60e1e8d768845f Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sun, 5 May 2013 00:26:18 +0400 Subject: [PATCH 15/24] more on performance tuning --- docs/guide/performance.md | 82 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 10 deletions(-) diff --git a/docs/guide/performance.md b/docs/guide/performance.md index a480a0b..58e8258 100644 --- a/docs/guide/performance.md +++ b/docs/guide/performance.md @@ -14,15 +14,22 @@ Preparing framework for production First thing you should do before deploying your application to production environment is to disable debug mode. A Yii application runs in debug mode if the constant -`YII_DEBUG` is defined as `true` in `index.php`. Debug mode is useful during -development stage, but it would impact performance because some components -cause extra burden in debug mode. For example, the message logger may record -additional debug information for every message being logged. +`YII_DEBUG` is defined as `true` in `index.php` so to disable debug the following +should be in your `index.php`: + +```php +defined('YII_DEBUG') or define('YII_DEBUG', false); +``` + +Debug mode is very useful during development stage, but it would impact performance +because some components cause extra burden in debug mode. For example, the message +logger may record additional debug information for every message being logged. ### Enabling PHP opcode cache Enabling the PHP opcode cache improves any PHP application performance and lowers -memory usage. Yii is no exception. It was tested with APC extension that caches +memory usage significantly. Yii is no exception. It was tested with +[APC PHP extension](http://php.net/manual/en/book.apc.php) that caches and optimizes PHP intermediate code and avoids the time spent in parsing PHP scripts for every incoming request. @@ -34,28 +41,69 @@ to save the time of parsing database schema. This can be done by setting the `protected/config/main.php`: ```php - +return array( + // ... + 'components' => array( + // ... + 'db' => array( + 'class' => 'yii\db\Connection', + 'dsn' => 'mysql:host=localhost;dbname=mydatabase', + 'username' => 'root', + 'password' => '', + 'enableSchemaCache' => true, + + // Duration of schema cache. + // 'schemaCacheDuration' => 3600, + + // Name of the cache component used. Default is 'cache'. + //'schemaCache' => 'cache', + ), + 'cache' => array( + 'class' => 'yii\caching\FileCache', + ), + ), +); ``` +Note that `cache` application component should be configured. + ### Combining and Minimizing Assets +TBD ### Using better storage for sessions -By default PHP uses plain files to handle sessions. It is OK for development and +By default PHP uses files to handle sessions. It is OK for development and small projects but when it comes to handling concurrent requests it's better to switch to another storage such as database. You can do so by configuring your application via `protected/config/main.php`: - ```php +return array( + // ... + 'components' => array( + 'session' => array( + 'class' => 'yii\web\DbSession', + + // Set the following if want to use DB component other than + // default 'db'. + // 'db' => 'mydb', + + // To override default session table set the following + // 'sessionTable' => 'my_session', + ), + ), +); ``` +You can use `CacheSession` to store sessions using cache. Note that some +cache storages such as memcached has no guaranteee that session data will not +be lost leading to unexpected logouts. Improving application --------------------- -### Using Caching Techniques +### Using Serverside Caching Techniques As described in the Caching section, Yii provides several caching solutions that may improve the performance of a Web application significantly. If the generation @@ -66,6 +114,10 @@ If a whole page remains relative static, we can use the page caching approach to save the rendering cost for the whole page. +### Leveraging HTTP to save procesing time and bandwidth + +TBD + ### Database Optimization Fetching data from database is often the main performance bottleneck in @@ -91,10 +143,20 @@ overwhelming data from database and exhausting the memory allocated to PHP. ### Using asArray +A good way to save memory and processing time on read-only pages is to use +ActiveRecord's `asArray` method. + +```php +``` + +TBD + ### Processing data in background In order to respond to user requests faster you can process heavy parts of the request later if there's no need for immediate response. - Cron jobs + console. -- queues + handlers. \ No newline at end of file +- queues + handlers. + +TBD \ No newline at end of file From 03cd47aed94512ddc117815bcca631c1a5763807 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sun, 5 May 2013 01:26:40 +0400 Subject: [PATCH 16/24] phpdoc typos --- framework/db/Query.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/db/Query.php b/framework/db/Query.php index 2239f5d..6f76265 100644 --- a/framework/db/Query.php +++ b/framework/db/Query.php @@ -483,7 +483,7 @@ class Query extends \yii\base\Component * Sets the ORDER BY part of the query. * @param string|array $columns the columns (and the directions) to be ordered by. * Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array - * (e.g. `array('id' => Query::SORT_ASC ASC, 'name' => Query::SORT_DESC)`). + * (e.g. `array('id' => Query::SORT_ASC, 'name' => Query::SORT_DESC)`). * The method will automatically quote the column names unless a column contains some parenthesis * (which means the column contains a DB expression). * @return Query the query object itself @@ -499,7 +499,7 @@ class Query extends \yii\base\Component * Adds additional ORDER BY columns to the query. * @param string|array $columns the columns (and the directions) to be ordered by. * Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array - * (e.g. `array('id' => Query::SORT_ASC ASC, 'name' => Query::SORT_DESC)`). + * (e.g. `array('id' => Query::SORT_ASC, 'name' => Query::SORT_DESC)`). * The method will automatically quote the column names unless a column contains some parenthesis * (which means the column contains a DB expression). * @return Query the query object itself From a948e7387231ee49d0664c114c40a9cce7b41eb8 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sun, 5 May 2013 01:27:13 +0400 Subject: [PATCH 17/24] example for using asArray --- docs/guide/performance.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/guide/performance.md b/docs/guide/performance.md index 58e8258..9a871dc 100644 --- a/docs/guide/performance.md +++ b/docs/guide/performance.md @@ -147,9 +147,28 @@ A good way to save memory and processing time on read-only pages is to use ActiveRecord's `asArray` method. ```php +class PostController extends Controller +{ + public function actionIndex() + { + $posts = Post::find()->orderBy('id DESC')->limit(100)->asArray()->all(); + echo $this->render('index', array( + 'posts' => $posts, + )); + } +} ``` -TBD +In the view you should access fields of each invidual record from `$posts` as array: + +```php +foreach($posts as $post) { + echo $post['title']."
"; +} +``` + +Note that you can use array notation even if `asArray` wasn't specified and you're +working with AR objects. ### Processing data in background From f3286df32880b46ec117d2eab8c5d783eec64952 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sun, 5 May 2013 01:44:34 +0400 Subject: [PATCH 18/24] Fixes #76 --- docs/view_renderers.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/view_renderers.md b/docs/view_renderers.md index 1d88d21..e26fe83 100644 --- a/docs/view_renderers.md +++ b/docs/view_renderers.md @@ -27,6 +27,9 @@ array( ) ``` +Note that Smarty and Twig are not bundled with Yii and you have to download and +unpack these yourself and then specify `twigPath` and `smartyPath` respectively. + Twig ---- From ddf67f0833d96d16a4f01667c1237d51558fa481 Mon Sep 17 00:00:00 2001 From: Alexander Kochetov Date: Sun, 5 May 2013 03:18:37 +0400 Subject: [PATCH 19/24] Code style fix --- framework/db/ActiveRelation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/db/ActiveRelation.php b/framework/db/ActiveRelation.php index f1b198b..97e2a8c 100644 --- a/framework/db/ActiveRelation.php +++ b/framework/db/ActiveRelation.php @@ -266,7 +266,7 @@ class ActiveRelation extends ActiveQuery { $attributes = array_keys($this->link); $values = array(); - if (count($attributes) ===1) { + if (count($attributes) === 1) { // single key $attribute = reset($this->link); foreach ($models as $model) { From 932ed70a7279056b2de4942f5282584a528580e7 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 4 May 2013 19:25:35 -0400 Subject: [PATCH 20/24] Fixes issue #99. --- framework/web/Request.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/web/Request.php b/framework/web/Request.php index ac19d5a..5e2f064 100644 --- a/framework/web/Request.php +++ b/framework/web/Request.php @@ -96,7 +96,7 @@ class Request extends \yii\base\Request */ public function getIsPostRequest() { - return isset($_SERVER['REQUEST_METHOD']) && !strcasecmp($_SERVER['REQUEST_METHOD'], 'POST'); + return $this->getRequestMethod() === 'POST'; } /** From 6166e70f201817c74cb4f5109ee7fb337196c40a Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 4 May 2013 20:17:43 -0400 Subject: [PATCH 21/24] Fixes issue #80 --- framework/db/Connection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/db/Connection.php b/framework/db/Connection.php index 797508a..f71b940 100644 --- a/framework/db/Connection.php +++ b/framework/db/Connection.php @@ -517,7 +517,7 @@ class Connection extends Component public function quoteSql($sql) { $db = $this; - return preg_replace_callback('/(\\{\\{([\w\-\. ]+)\\}\\}|\\[\\[([\w\-\. ]+)\\]\\])/', + return preg_replace_callback('/(\\{\\{([%\w\-\. ]+)\\}\\}|\\[\\[([\w\-\. ]+)\\]\\])/', function($matches) use($db) { if (isset($matches[3])) { return $db->quoteColumnName($matches[3]); From 6e779e02d655a222157aeeb38112325ba0ae997c Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 4 May 2013 21:24:00 -0400 Subject: [PATCH 22/24] Fixed issue #7: ArrayHelper::multisort is not compatible with PHP 5.3 --- framework/helpers/base/ArrayHelper.php | 40 +++++++++++++++--------- tests/unit/framework/helpers/ArrayHelperTest.php | 11 ++++++- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/framework/helpers/base/ArrayHelper.php b/framework/helpers/base/ArrayHelper.php index 9870542..8a9a38c 100644 --- a/framework/helpers/base/ArrayHelper.php +++ b/framework/helpers/base/ArrayHelper.php @@ -236,15 +236,17 @@ class ArrayHelper * To sort by multiple keys, provide an array of keys here. * @param boolean|array $ascending whether to sort in ascending or descending order. When * sorting by multiple keys with different ascending orders, use an array of ascending flags. - * @param integer|array $sortFlag the PHP sort flag. Valid values include: - * `SORT_REGULAR`, `SORT_NUMERIC`, `SORT_STRING`, and `SORT_STRING | SORT_FLAG_CASE`. The last - * value is for sorting strings in case-insensitive manner. Please refer to - * See [PHP manual](http://php.net/manual/en/function.sort.php) for more details. - * When sorting by multiple keys with different sort flags, use an array of sort flags. + * @param integer|array $sortFlag the PHP sort flag. Valid values include + * `SORT_REGULAR`, `SORT_NUMERIC`, `SORT_STRING`, `SORT_LOCALE_STRING` and `SORT_NATURAL`. + * and `SORT_STRING | SORT_FLAG_CASE`. Please refer to [PHP manual](http://php.net/manual/en/function.sort.php) + * for more details. When sorting by multiple keys with different sort flags, use an array of sort flags. + * @param boolean|array $caseSensitive whether to sort string in case-sensitive manner. This parameter + * is used only when `$sortFlag` is either `SORT_STRING` or `SORT_NATURAL`. + * When sorting by multiple keys with different case sensitivities, use an array of boolean values. * @throws InvalidParamException if the $ascending or $sortFlag parameters do not have * correct number of elements as that of $key. */ - public static function multisort(&$array, $key, $ascending = true, $sortFlag = SORT_REGULAR) + public static function multisort(&$array, $key, $ascending = true, $sortFlag = SORT_REGULAR, $caseSensitive = true) { $keys = is_array($key) ? $key : array($key); if (empty($keys) || empty($array)) { @@ -259,20 +261,30 @@ class ArrayHelper if (is_scalar($sortFlag)) { $sortFlag = array_fill(0, $n, $sortFlag); } elseif (count($sortFlag) !== $n) { - throw new InvalidParamException('The length of $ascending parameter must be the same as that of $keys.'); + throw new InvalidParamException('The length of $sortFlag parameter must be the same as that of $keys.'); + } + if (is_scalar($caseSensitive)) { + $caseSensitive = array_fill(0, $n, $caseSensitive); + } elseif (count($caseSensitive) !== $n) { + throw new InvalidParamException('The length of $caseSensitive parameter must be the same as that of $keys.'); } $args = array(); foreach ($keys as $i => $key) { $flag = $sortFlag[$i]; - if ($flag == (SORT_STRING | SORT_FLAG_CASE)) { - $flag = SORT_STRING; - $column = array(); - foreach (static::getColumn($array, $key) as $k => $value) { - $column[$k] = strtolower($value); + $cs = $caseSensitive[$i]; + if (!$cs && ($flag === SORT_STRING || $flag === SORT_NATURAL)) { + if (defined('SORT_FLAG_CASE')) { + $flag = $flag | SORT_FLAG_CASE; + $args[] = static::getColumn($array, $key); + } else { + $column = array(); + foreach (static::getColumn($array, $key) as $k => $value) { + $column[$k] = mb_strtolower($value); + } + $args[] = $column; } - $args[] = $column; } else { - $args[] = static::getColumn($array, $key); + $args[] = static::getColumn($array, $key); } $args[] = $ascending[$i] ? SORT_ASC : SORT_DESC; $args[] = $flag; diff --git a/tests/unit/framework/helpers/ArrayHelperTest.php b/tests/unit/framework/helpers/ArrayHelperTest.php index 187217f..b3ffabf 100644 --- a/tests/unit/framework/helpers/ArrayHelperTest.php +++ b/tests/unit/framework/helpers/ArrayHelperTest.php @@ -40,11 +40,20 @@ class ArrayHelperTest extends \yii\test\TestCase $array = array( array('name' => 'a', 'age' => 3), array('name' => 'b', 'age' => 2), + array('name' => 'B', 'age' => 4), array('name' => 'A', 'age' => 1), ); - ArrayHelper::multisort($array, array('name', 'age'), SORT_ASC, array(SORT_STRING|SORT_FLAG_CASE, SORT_REGULAR)); + + ArrayHelper::multisort($array, array('name', 'age'), SORT_ASC, array(SORT_STRING, SORT_REGULAR)); + $this->assertEquals(array('name' => 'A', 'age' => 1), $array[0]); + $this->assertEquals(array('name' => 'B', 'age' => 4), $array[1]); + $this->assertEquals(array('name' => 'a', 'age' => 3), $array[2]); + $this->assertEquals(array('name' => 'b', 'age' => 2), $array[3]); + + ArrayHelper::multisort($array, array('name', 'age'), SORT_ASC, array(SORT_STRING, SORT_REGULAR), false); $this->assertEquals(array('name' => 'A', 'age' => 1), $array[0]); $this->assertEquals(array('name' => 'a', 'age' => 3), $array[1]); $this->assertEquals(array('name' => 'b', 'age' => 2), $array[2]); + $this->assertEquals(array('name' => 'B', 'age' => 4), $array[3]); } } From dc73c916fc4a864ac6c9f15b521931fb884360f2 Mon Sep 17 00:00:00 2001 From: Taufan Aditya Date: Sun, 5 May 2013 09:39:43 +0700 Subject: [PATCH 23/24] Fix unsupported flag in php 5.3.x environment [ArrayHelper::multisort] --- framework/helpers/base/ArrayHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/helpers/base/ArrayHelper.php b/framework/helpers/base/ArrayHelper.php index 8a9a38c..5c94887 100644 --- a/framework/helpers/base/ArrayHelper.php +++ b/framework/helpers/base/ArrayHelper.php @@ -272,7 +272,7 @@ class ArrayHelper foreach ($keys as $i => $key) { $flag = $sortFlag[$i]; $cs = $caseSensitive[$i]; - if (!$cs && ($flag === SORT_STRING || $flag === SORT_NATURAL)) { + if (!$cs && ($flag === SORT_STRING)) { if (defined('SORT_FLAG_CASE')) { $flag = $flag | SORT_FLAG_CASE; $args[] = static::getColumn($array, $key); From cfc958201fb32f089cc5bbec2f5ccdf75f44f7c1 Mon Sep 17 00:00:00 2001 From: Taufan Aditya Date: Sun, 5 May 2013 10:00:59 +0700 Subject: [PATCH 24/24] Remove reference to php 5.4-only constants in arrayhelper --- framework/helpers/base/ArrayHelper.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/helpers/base/ArrayHelper.php b/framework/helpers/base/ArrayHelper.php index 5c94887..5f72fe4 100644 --- a/framework/helpers/base/ArrayHelper.php +++ b/framework/helpers/base/ArrayHelper.php @@ -237,11 +237,11 @@ class ArrayHelper * @param boolean|array $ascending whether to sort in ascending or descending order. When * sorting by multiple keys with different ascending orders, use an array of ascending flags. * @param integer|array $sortFlag the PHP sort flag. Valid values include - * `SORT_REGULAR`, `SORT_NUMERIC`, `SORT_STRING`, `SORT_LOCALE_STRING` and `SORT_NATURAL`. - * and `SORT_STRING | SORT_FLAG_CASE`. Please refer to [PHP manual](http://php.net/manual/en/function.sort.php) + * `SORT_REGULAR`, `SORT_NUMERIC`, `SORT_STRING` and `SORT_LOCALE_STRING`. + * Please refer to [PHP manual](http://php.net/manual/en/function.sort.php) * for more details. When sorting by multiple keys with different sort flags, use an array of sort flags. * @param boolean|array $caseSensitive whether to sort string in case-sensitive manner. This parameter - * is used only when `$sortFlag` is either `SORT_STRING` or `SORT_NATURAL`. + * is used only when `$sortFlag` is `SORT_STRING`. * When sorting by multiple keys with different case sensitivities, use an array of boolean values. * @throws InvalidParamException if the $ascending or $sortFlag parameters do not have * correct number of elements as that of $key.