Changeset 8376
- Timestamp:
- 04/09/08 22:44:11 (3 months ago)
- Files:
-
- doc/trunk/book/01-Introducing-Symfony.txt (modified) (2 diffs)
- doc/trunk/book/02-Exploring-Symfony-s-Code.txt (modified) (8 diffs)
- doc/trunk/book/03-Running-Symfony.txt (modified) (19 diffs)
- doc/trunk/book/04-The-Basics-of-Page-Creation.txt (modified) (14 diffs)
- doc/trunk/book/05-Configuring-Symfony.txt (modified) (13 diffs)
- doc/trunk/book/06-Inside-the-Controller-Layer.txt (modified) (45 diffs)
- doc/trunk/book/07-Inside-the-View-Layer.txt (modified) (24 diffs)
- doc/trunk/book/08-Inside-the-Model-Layer.txt (modified) (10 diffs)
- doc/trunk/book/09-Links-and-the-Routing-System.txt (modified) (14 diffs)
- doc/trunk/book/10-Forms.txt (modified) (8 diffs)
- doc/trunk/book/11-Ajax-Integration.txt (modified) (5 diffs)
- doc/trunk/book/12-Caching.txt (modified) (22 diffs)
- doc/trunk/book/13-I18n-and-L10n.txt (modified) (7 diffs)
- doc/trunk/book/14-Generators.txt (modified) (20 diffs)
- doc/trunk/book/15-Unit-and-Functional-Testing.txt (modified) (17 diffs)
- doc/trunk/book/16-Application-Management-Tools.txt (modified) (23 diffs)
- doc/trunk/book/17-Extending-Symfony.txt (modified) (27 diffs)
- doc/trunk/book/18-Performance.txt (modified) (8 diffs)
- doc/trunk/book/19-Mastering-Symfony-s-Configuration-Files.txt (modified) (21 diffs)
- doc/trunk/cookbook/alternative_schema.txt (copied) (copied from doc/branches/1.1/cookbook/alternative_schema.txt)
- doc/trunk/cookbook/cli.txt (modified) (11 diffs)
- doc/trunk/cookbook/pager.txt (modified) (7 diffs)
- doc/trunk/tutorial/my-first-project.txt (modified) (30 diffs)
- doc/trunk/tutorial/symfony-ajax.txt (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
doc/trunk/book/01-Introducing-Symfony.txt
r6117 r8376 100 100 ### PHP 5 101 101 102 Symfony is developed in PHP 5 ([http://www.php.net/](http://www.php.net/)) and dedicated to building web applications with the same language. Therefore, a solid understanding of PHP 5 is required to get the most out of the framework. 102 Symfony is developed in PHP 5 ([http://www.php.net/](http://www.php.net/)) and dedicated to building web applications with the same language. Therefore, a solid understanding of PHP 5 is required to get the most out of the framework. The minimal version of PHP required to run symfony is PHP 5.1. 103 103 104 104 Developers who already know PHP 4 but not PHP 5 should mainly focus on the language's new object-oriented model. … … 184 184 And that's it. Imagine how long it would have required to write a SQL query doing the same thing! 185 185 186 Propel, another open source project, is currently one of the best object/relational abstraction layers for PHP 5. Symfony integrates Propel seamlessly into the framework, so most of the data manipulation described in this book follows the Propel syntax. This book will describe how to use the Propel objects, but for a more complete reference, a visit to the Propel website ([http://propel.phpdb.org/trac/](http://propel.phpdb.org/trac/)) is recommended.186 Propel, another open source project, is currently one of the best object/relational abstraction layers for PHP 5. Symfony integrates Propel seamlessly as its default ORM, so most of the data manipulation described in this book follows the Propel syntax. This book will describe how to use the Propel objects, but for a more complete reference, a visit to the Propel website ([http://propel.phpdb.org/trac/](http://propel.phpdb.org/trac/)) is recommended. 187 187 188 188 ### Rapid Application Development (RAD) doc/trunk/book/02-Exploring-Symfony-s-Code.txt
r4537 r8376 543 543 templates/ 544 544 indexSuccess.php 545 validate/546 545 547 546 Table 2-3 describes the module subdirectories. … … 555 554 `lib/` | Stores classes and libraries specific to the module. 556 555 `templates/` | Contains the templates corresponding to the actions of the module. A default template, called `indexSuccess.php`, is created during module setup. 557 `validate/` | Dedicated to configuration files used for form validation (discussed in Chapter 10).558 556 559 557 >**NOTE** 560 >The `config/`, `lib/`, and `validate/` directories are empty for a new module.558 >The `config/`, and `lib/` directories are empty for a new module. 561 559 562 560 #### Web Tree Structure … … 591 589 ### Parameter Holders 592 590 593 Many of the symfony classes contain a parameter holder. It is a convenient way to encapsulate attributes with clean getter and setter methods. For instance, the sfRe sponseclass holds a parameter holder that you can retrieve by calling the `getParameterHolder()` method. Each parameter holder stores data the same way, as illustrated in Listing 2-15.594 595 Listing 2-15 - Using the `sfRe sponse` Parameter Holder596 597 [php] 598 $re sponse->getParameterHolder()->set('foo', 'bar');599 echo $re sponse->getParameterHolder()->get('foo');591 Many of the symfony classes contain a parameter holder. It is a convenient way to encapsulate attributes with clean getter and setter methods. For instance, the sfRequest class holds a parameter holder that you can retrieve by calling the `getParameterHolder()` method. Each parameter holder stores data the same way, as illustrated in Listing 2-15. 592 593 Listing 2-15 - Using the `sfRequest` Parameter Holder 594 595 [php] 596 $request->getParameterHolder()->set('foo', 'bar'); 597 echo $request->getParameterHolder()->get('foo'); 600 598 => 'bar' 601 599 602 Most of the classes using a parameter holder provide proxy methods to shorten the code needed for get/set operations. This is the case for the `sfRe sponse` object, so you can do the same as in Listing 2-15 with the code of Listing 2-16.603 604 Listing 2-16 - Using the `sfRe sponse` Parameter Holder Proxy Methods605 606 [php] 607 $re sponse->setParameter('foo', 'bar');608 echo $re sponse->getParameter('foo');600 Most of the classes using a parameter holder provide proxy methods to shorten the code needed for get/set operations. This is the case for the `sfRequest` object, so you can do the same as in Listing 2-15 with the code of Listing 2-16. 601 602 Listing 2-16 - Using the `sfRequest` Parameter Holder Proxy Methods 603 604 [php] 605 $request->setParameter('foo', 'bar'); 606 echo $request->getParameter('foo'); 609 607 => 'bar' 610 608 … … 615 613 [php] 616 614 // The 'foobar' parameter is not defined, so the getter returns an empty value 617 echo $re sponse->getParameter('foobar');615 echo $request->getParameter('foobar'); 618 616 => null 619 617 620 618 // A default value can be used by putting the getter in a condition 621 if ($re sponse->hasParameter('foobar'))622 { 623 echo $re sponse->getParameter('foobar');619 if ($request->hasParameter('foobar')) 620 { 621 echo $request->getParameter('foobar'); 624 622 } 625 623 else … … 630 628 631 629 // But it is much faster to use the second getter argument for that 632 echo $re sponse->getParameter('foobar', 'default');630 echo $request->getParameter('foobar', 'default'); 633 631 => default 634 632 635 The parameter holders even support namespaces. If you specify a third argument to a setter or a getter, it is used as a namespace, and the parameter will be defined only within that namespace. Listing 2-18 shows an example.636 637 Listing 2-18 - Using the `sf Response` Parameter Holder Namespace638 639 [php] 640 $ response->setParameter('foo', 'bar1');641 $ response->setParameter('foo', 'bar2', 'my/name/space');642 echo $ response->getParameter('foo');633 Some symfony core classes also use a parameter holder that support namespaces (thanks to the `sfNamespacedParameterHolder` class). If you specify a third argument to a setter or a getter, it is used as a namespace, and the parameter will be defined only within that namespace. Listing 2-18 shows an example. 634 635 Listing 2-18 - Using the `sfUser` Parameter Holder Namespace 636 637 [php] 638 $user->setAttribute('foo', 'bar1'); 639 $user->setAttribute('foo', 'bar2', 'my/name/space'); 640 echo $user->getAttribute('foo'); 643 641 => 'bar1' 644 echo $ response->getParameter('foo', null, 'my/name/space');642 echo $user->getAttribute('foo', null, 'my/name/space'); 645 643 => 'bar2' 646 644 … … 652 650 class MyClass 653 651 { 654 protected $parameter _holder = null;655 656 public function initialize ($parameters = array())652 protected $parameterHolder = null; 653 654 public function initialize($parameters = array()) 657 655 { 658 $this->parameter _holder = new sfParameterHolder();659 $this->parameter _holder->add($parameters);656 $this->parameterHolder = new sfParameterHolder(); 657 $this->parameterHolder->add($parameters); 660 658 } 661 659 662 660 public function getParameterHolder() 663 661 { 664 return $this->parameter _holder;662 return $this->parameterHolder; 665 663 } 666 664 } … … 676 674 define('SF_FOO', 'bar'); 677 675 echo SF_FOO; 678 // Symfony uses the sfConfig object 676 677 // symfony uses the sfConfig object 679 678 sfConfig::set('sf_foo', 'bar'); 680 679 echo sfConfig::get('sf_foo'); … … 700 699 701 700 >**NOTE** 702 >For better performance, the symfony autoloading scans a list of directories (defined in an internal configuration file) during the first request. It then registers all the classes these directories contain and stores the class/file correspondence in a PHP file as an associative array. That way, future requests don't need to do the directory scan anymore. This is why you need to clear the cache every time you add or move a class file in your project by calling the `symfony c lear-cache` command (except in the development environment). You will learn more about the cache in Chapter 12, and about the autoloading configuration in Chapter 19.701 >For better performance, the symfony autoloading scans a list of directories (defined in an internal configuration file) during the first request. It then registers all the classes these directories contain and stores the class/file correspondence in a PHP file as an associative array. That way, future requests don't need to do the directory scan anymore. This is why you need to clear the cache every time you add or move a class file in your project by calling the `symfony cache:clear` command (except in the development environment). You will learn more about the cache in Chapter 12, and about the autoloading configuration in Chapter 19. 703 702 704 703 Summary doc/trunk/book/03-Running-Symfony.txt
r6117 r8376 4 4 As you've learned in previous chapters, the symfony framework is a set of files written in PHP. A symfony project uses these files, so installing symfony means getting these files and making them available for the project. 5 5 6 Being a PHP 5 framework, symfony requires PHP 5. Make sure you have it installed by opening a command line and typing this command:6 Symfony requires at least PHP 5.1. Make sure you have it installed by opening a command line and typing this command: 7 7 8 8 > php -v 9 9 10 PHP 5.2. 0 (cli) (built: Nov 2 2006 11:57:36)11 Copyright (c) 1997-200 6The PHP Group12 Zend Engine v2.2.0, Copyright (c) 1998-200 6Zend Technologies13 14 If the version number is 5. 0or higher, then you're ready for the installation, as described in this chapter.10 PHP 5.2.5 (cli) (built: Nov 20 2007 16:55:40) 11 Copyright (c) 1997-2007 The PHP Group 12 Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies 13 14 If the version number is 5.1 or higher, then you're ready for the installation, as described in this chapter. 15 15 16 16 Installing the Sandbox … … 19 19 If you just want to see what symfony is capable of, you'll probably go for the fast installation. In that case, you need the sandbox. 20 20 21 The sandbox is a simple archive of files. It contains an empty symfony project including all the required libraries (symfony, pake,lime, Creole, Propel, and Phing), a default application, and basic configuration. It will work out of the box, without specific server configuration or any additional packages.22 23 To install it, download the sandbox archive from [http://www.symfony-project.org/get/sf_sandbox .tgz](http://www.symfony-project.org/get/sf_sandbox.tgz). Unpack it under the root web directory configured for your server (usually `web/` or `www/`). For the purposes of uniformity, this chapter will assume you unpacked it to the directory `sf_sandbox/`.21 The sandbox is a simple archive of files. It contains an empty symfony project including all the required libraries (symfony, lime, Creole, Propel, and Phing), a default application, and basic configuration. It will work out of the box, without specific server configuration or any additional packages. 22 23 To install it, download the sandbox archive from [http://www.symfony-project.org/get/sf_sandbox_1_1.tgz](http://www.symfony-project.org/get/sf_sandbox_1_1.tgz). Unpack it under the root web directory configured for your server (usually `web/` or `www/`). For the purposes of uniformity, this chapter will assume you unpacked it to the directory `sf_sandbox/`. 24 24 25 25 >**CAUTION** 26 26 >Having all the files under the root web directory is fine for your own tests in a local host, but is a bad practice in a production server. It makes all the internals of your application visible to end users. 27 27 28 Test your installation by executing the symfony CLI. Go to the new `sf_sandbox/` directory and type the following on a *nix system: 29 30 > ./symfony -V 31 32 On Windows, issue this command: 33 34 > symfony -V 28 Test your installation by executing the symfony CLI. Go to the new `sf_sandbox/` directory and type the following: 29 30 > php symfony -V 35 31 36 32 You should see the sandbox version number: 37 33 38 symfony version 1. 0.034 symfony version 1.1.0 (/path/to/the/symfony/lib/dir/used/by/the/sandbox) 39 35 40 36 Now make sure that your web server can browse the sandbox by requesting this URL: … … 52 48 To uninstall a sandbox, just remove the `sf_sandbox/` directory from your `web/` folder. 53 49 54 Installing the Symfony Libraries50 Installing the symfony Libraries 55 51 -------------------------------- 56 52 … … 66 62 Symfony integrates a few other packages: 67 63 68 * pake is a CLI utility.69 64 * lime is a unit testing utility. 70 65 * Creole is a database abstraction engine. Just like PHP Data Objects (PDO), it provides an interface between your code and the database SQL code, and makes it possible to switch to another engine. 71 66 * Propel is for ORM. It provides object persistence and query service. 72 * Phing is a CLI for Propel. 73 74 Pake and lime are developed by the symfony team. Creole, Propel, and Phing come from another team and are released under the GNU Lesser Public General License (LGPL). All these packages are bundled with symfony. 75 76 ### Installing the Symfony PEAR Package 67 * Phing is a build system used by Propel to generate the model classes. 68 69 Lime are developed by the symfony team. Creole, Propel, and Phing come from another team and are released under the GNU Lesser Public General License (LGPL). All these packages are bundled with symfony. 70 71 >**TIP** 72 >The symfony framework is licensed under a MIT license. 73 >All the copyrights for the bundled third party libraries can be found in the `COPYRIGHT` file and the associated licenses are stored in the `licenses/` directory. 74 75 ### Installing the symfony PEAR Package 77 76 78 77 The symfony PEAR package contains the symfony libraries and all its dependencies. It also contains a script that will extend your CLI to include the `symfony` command. … … 90 89 > pear install symfony/symfony 91 90 92 downloading symfony-1. 0.0.tgz ...93 Starting to download symfony-1. 0.0.tgz (1,283,270 bytes)91 downloading symfony-1.1.0.tgz ... 92 Starting to download symfony-1.1.0.tgz (1,283,270 bytes) 94 93 ................................................................. 95 94 ................................................................. 96 95 .............done: 1,283,270 bytes 97 install ok: channel://pear.symfony-project.com/symfony-1. 0.096 install ok: channel://pear.symfony-project.com/symfony-1.1.0 98 97 99 98 That's it. The symfony files and CLI are installed. Check that the installation succeeded by calling the new `symfony` command line, asking for the version number: … … 101 100 > symfony -V 102 101 103 symfony version 1.0.0 104 105 >**TIP** 106 >If you prefer to install the most recent beta, which has the latest bug fixes and enhancements, type `pear install symfony/symfony-beta` instead. Beta releases are not completely stable and are generally not recommended for production environments. 102 symfony version 1.1.0 (/path/to/the/pear/symfony/lib/dir) 107 103 108 104 The symfony libraries are now installed in directories as follows: 109 105 110 106 * `$php_dir/symfony/` contains the main libraries. 111 * `$data_dir/symfony/` contains the skeleton of symfony applications; default modules; and configuration, i18n data, and so on.107 * `$data_dir/symfony/` contains the web assets used by symfony default modules; and command line scripts. 112 108 * `$doc_dir/symfony/` contains the documentation. 113 109 * `$test_dir/symfony/` contains unit tests. … … 117 113 > pear config-show 118 114 119 ### Checking Out Symfony from the SVN Repository115 ### Checking Out symfony from the SVN Repository 120 116 121 117 For production servers, or when PEAR is not an option, you can download the latest version of the symfony libraries directly from the symfony Subversion repository by requesting a checkout: … … 123 119 > mkdir /path/to/symfony 124 120 > cd /path/to/symfony 125 > svn checkout http://svn.symfony-project.com/tags/RELEASE_1_ 0_0/ .121 > svn checkout http://svn.symfony-project.com/tags/RELEASE_1_1_0/ . 126 122 127 123 The `symfony` command, available only for PEAR installations, is a call to the `/path/to/symfony/data/bin/symfony` script. So the following would be the equivalent to the `symfony -V` command for an SVN installation: … … 129 125 > php /path/to/symfony/data/bin/symfony -V 130 126 131 symfony version 1. 0.0132 133 If you chose an SVN installation, you probably already have an existing symfony project. For this project to make use of the symfony files, you need to change the two variables defined in your project's `config/config.php` file, as follows:127 symfony version 1.1.0 (/path/to/the/svn/symfony/lib/dir) 128 129 If you chose an SVN installation, you probably already have an existing symfony project. For this project to make use of the symfony files, you need to change the a path defined in your project's `lib/ProjectConfiguration.class.php` file, as follows: 134 130 135 131 [php] 136 132 <?php 137 133 138 $sf_symfony_lib_dir = '/path/to/symfony/lib/'; 139 $sf_symfony_data_dir = '/path/to/symfony/data/'; 134 require_once '/path/to/symfony/lib/autoload/sfCoreAutoload.class.php'; 135 sfCoreAutoload::register(); 136 137 class ProjectConfiguration extends sfProjectConfiguration 138 { 140 139 141 140 Chapter 19 proposes other ways to link a project with a symfony installation (including symbolic links and relative paths). 142 141 143 142 >**TIP** 144 >Alternatively, you can also download the PEAR package ([http://pear.symfony-project.com/get/symfony-1. 0.0.tgz](http://pear.symfony-project.com/get/symfony-1.0.0.tgz)) and unpack it somewhere. You will have the same result as with a checkout.143 >Alternatively, you can also download the PEAR package ([http://pear.symfony-project.com/get/symfony-1.1.0.tgz](http://pear.symfony-project.com/get/symfony-1.1.0.tgz)) and unpack it somewhere. You will have the same result as with a checkout. 145 144 146 145 Setting Up an Application … … 157 156 > mkdir ~/myproject 158 157 > cd ~/myproject 159 > symfony init-project myproject158 > symfony generate:project myproject 160 159 161 160 For an SVN installation, create a project with these commands: … … 163 162 > mkdir ~/myproject 164 163 > cd ~/myproject 165 > php /path/to/symfony/data/bin/symfony init-project myproject 166 167 The `symfony` command must always be called from the project's root directory (`myproject/` in the preceding examples), because all the tasks performed by this command are project-specific. 164 > php /path/to/symfony/data/bin/symfony generate:project myproject 168 165 169 166 Symfony will create a directory structure that looks like this: … … 182 179 183 180 >**TIP** 184 >The ` init-project` task adds a `symfony` script in the project root directory. This PHP script does the same as the `symfony` command installed by PEAR, so you can call `php symfony` instead of `symfony` if you don't have native command-line support (for SVN installations).181 >The `generate:project` task adds a `symfony` script in the project root directory. This PHP script does the same as the `symfony` command installed by PEAR, so you can call `php symfony` instead of `symfony` if you don't have native command-line support (for SVN installations). 185 182 186 183 ### Creating the Application 187 184 188 The project is not yet ready to be viewed, because it requires at least one application. To initialize it, use the `symfony init-app` command and pass the name of the application as an argument:189 190 > symfony init-app myapp191 192 This will create a ` myapp/` directory in the `apps/` folder of the project root, with a default application configuration and a set of directories ready to host the file of your website:185 The project is not yet ready to be viewed, because it requires at least one application. To initialize it, use the `symfony generate:app` command and pass the name of the application as an argument: 186 187 > php symfony generate:app frontend 188 189 This will create a `frontend/` directory in the `apps/` folder of the project root, with a default application configuration and a set of directories ready to host the file of your website: 193 190 194 191 apps/ 195 myapp/192 frontend/ 196 193 config/ 197 194 i18n/ … … 204 201 web/ 205 202 index.php 206 myapp_dev.php 207 208 `index.php` is the production front controller of the new application. Because you created the first application of the project, symfony created a file called `index.php` instead of `myapp.php` (if you now add a new application called `mynewapp`, the new production front controller will be named `mynewapp.php`). To run your application in the development environment, call the front controller `myapp_dev.php`. You'll learn more about these environments in Chapter 5. 203 frontend_dev.php 204 205 `index.php` is the production front controller of the new application. Because you created the first application of the project, symfony created a file called `index.php` instead of `frontend.php` (if you now add a new application called `backend`, the new production front controller will be named `backend.php`). To run your application in the development environment, call the front controller `frontend_dev.php`. You'll learn more about these environments in Chapter 5. 206 207 The `symfony` command must always be called from the project's root directory (`myproject/` in the preceding examples), because all the tasks performed by this command are project-specific. 209 208 210 209 Configuring the Web Server … … 236 235 In the configuration in Listing 3-1, the `$sf_symfony_data_dir` placeholder must be replaced by the actual path. For example, for a PEAR installation in *nix, you should type something like this: 237 236 238 Alias /sf /usr/local/lib/php/data/symfony/web/sf237 Alias /sf /usr/local/lib/php/data/symfony/web/sf 239 238 240 239 >**NOTE** … … 243 242 Restart Apache, and that's it. Your newly created application can now be called and viewed through a standard web browser at the following URL: 244 243 245 http://localhost/ myapp_dev.php/244 http://localhost/frontend_dev.php/ 246 245 247 246 You should see a congratulations page similar to the one shown earlier in Figure 3-1. … … 259 258 > 260 259 > 261 >For Internet Information Services (IIS), you will need `isapi/rewrite` installed and running. Check the symfony online documentationfor a detailed IIS installation guide.260 >For Internet Information Services (IIS), you will need `isapi/rewrite` installed and running. Check the symfony online cookbook for a detailed IIS installation guide. 262 261 263 262 ### Configuring a Shared-Host Server … … 270 269 Let's imagine that your shared host requires that the web folder is named `www/` instead of `web/`, and that it doesn't give you access to the `httpd.conf` file, but only to an `.htaccess` file in the web folder. 271 270 272 In a symfony project, every path to a directory is configurable. Chapter 19 will tell you more about it, but in the meantime, you can still rename the `web` directory to `www` and have the application take it into account by changing the configuration, as shown in Listing 3-2. These lines are to be added to the end of the application `config.php` file.273 274 Listing 3-2 - Changing the Default Directory Structure Settings, in ` apps/myapp/config/config.php`271 In a symfony project, every path to a directory is configurable. Chapter 19 will tell you more about it, but in the meantime, you can still rename the `web` directory to `www` and have the application take it into account by changing the configuration, as shown in Listing 3-2. These lines are to be added to the end of the `lib/ProjectConfiguration.class.php` file. 272 273 Listing 3-2 - Changing the Default Directory Structure Settings, in `lib/ProjectConfiguration.class.php` 275 274 276 275 [php] 277 $sf_root_dir = sfConfig::get('sf_root_dir'); 278 sfConfig::add(array( 279 'sf_web_dir_name' => $sf_web_dir_name = 'www', 280 'sf_web_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.$sf_web_dir_name, 281 'sf_upload_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.$sf_web_dir_name.DIRECTORY_SEPARATOR.sfConfig::get('sf_upload_dir_name'), 282 )); 276 class ProjectConfiguration extends sfProjectConfiguration 277 { 278 public function setup() 279 { 280 $this->setWebDir($this->getRootDir().'/www'); 281 } 282 } 283 283 284 284 The project web root contains an .htaccess file by default. It is shown in Listing 3-3. Modify it as necessary to match your shared host requirements. … … 291 291 RewriteEngine On 292 292 293 # uncomment the following line, if you are having trouble 294 # getting no_script_name to work 295 #RewriteBase / 296 293 297 # we skip all files with .something 294 RewriteCond %{REQUEST_URI} \..+$295 RewriteCond %{REQUEST_URI} !\.html$296 RewriteRule .* - [L]298 #RewriteCond %{REQUEST_URI} \..+$ 299 #RewriteCond %{REQUEST_URI} !\.html$ 300 #RewriteRule .* - [L] 297 301 298 302 # we check if the .html version is here (caching) … … 305 309 </IfModule> 306 310 307 # big crash from our front web controller308 ErrorDocument 500 "<h2>Application error</h2>symfony applicationfailed to start properly"309 310 311 You should now be ready to browse your application. Check the congratulation page by requesting this URL: 311 312 312 http://www.example.com/ myapp_dev.php/313 http://www.example.com/frontend_dev.php/ 313 314 314 315 >**SIDEBAR** doc/trunk/book/04-The-Basics-of-Page-Creation.txt
r4908 r8376 11 11 As Chapter 2 explained, symfony groups pages into modules. Before creating a page, you need to create a module, which is initially an empty shell with a file structure that symfony can recognize. 12 12 13 The symfony command line automates the creation of modules. You just need to call the ` init-module` task with the application name and the module name as arguments. In the previous chapter, you created a `myapp` application. To add a `mymodule` module to this application, type the following commands:13 The symfony command line automates the creation of modules. You just need to call the `generate:module` task with the application name and the module name as arguments. In the previous chapter, you created a `frontend` application. To add a `content` module to this application, type the following commands: 14 14 15 15 > cd ~/myproject 16 > symfony init-module myapp mymodule 17 18 >> dir+ ~/myproject/apps/myapp/modules/mymodule 19 >> dir+ ~/myproject/apps/myapp/modules/mymodule/actions 20 >> file+ ~/myproject/apps/myapp/modules/mymodule/actions/actions.class.php 21 >> dir+ ~/myproject/apps/myapp/modules/mymodule/config 22 >> dir+ ~/myproject/apps/myapp/modules/mymodule/lib 23 >> dir+ ~/myproject/apps/myapp/modules/mymodule/templates 24 >> file+ ~/myproject/apps/myapp/modules/mymodule/templates/indexSuccess.php 25 >> dir+ ~/myproject/apps/myapp/modules/mymodule/validate 26 >> file+ ~/myproject/test/functional/myapp/mymoduleActionsTest.php 27 >> tokens ~/myproject/test/functional/myapp/mymoduleActionsTest.php 28 >> tokens ~/myproject/apps/myapp/modules/mymodule/actions/actions.class.php 29 >> tokens ~/myproject/apps/myapp/modules/mymodule/templates/indexSuccess.php 30 31 Apart from the `actions/`, `config/`, `lib/`, `templates/`, and `validate/` directories, this command created only three files. The one in the test/ folder concerns unit tests, and you don't need to bother with it until Chapter 15. The `actions.class.php` (shown in Listing 4-1) forwards to the default module congratulation page. The `templates/indexSuccess.php` file is empty. 16 > php symfony generate:module frontend content 17 18 >> dir+ ~/myproject/apps/frontend/modules/content/actions 19 >> file+ ~/myproject/apps/frontend/modules/content/actions/actions.class.php 20 >> dir+ ~/myproject/apps/frontend/modules/content/templates 21 >> file+ ~/myproject/apps/frontend/modules/content/templates/indexSuccess.php 22 >> file+ ~/myproject/test/functional/frontend/contentActionsTest.php 23 >> tokens ~/myproject/test/functional/frontend/contentActionsTest.php 24 >> tokens ~/myproject/apps/frontend/modules/content/actions/actions.class.php 25 >> tokens ~/myproject/apps/frontend/modules/content/templates/indexSuccess.php 26 27 Apart from the `actions/`, and `templates/` directories, this command created only three files. The one in the test/ folder concerns functional tests, and you don't need to bother with it until Chapter 15. The `actions.class.php` (shown in Listing 4-1) forwards to the default module congratulation page. The `templates/indexSuccess.php` file is empty. 32 28 33 29 Listing 4-1 - The Default Generated Action, in `actions/actions.class.php` … … 36 32 <?php 37 33 38 class mymoduleActions extends sfActions34 class contentActions extends sfActions 39 35 { 40 36 public function executeIndex() … … 49 45 For each new module, symfony creates a default `index` action. It is composed of an action method called `executeIndex` and a template file called `indexSuccess.php`. The meanings of the `execute` prefix and `Success` suffix will be explained in Chapters 6 and 7, respectively. In the meantime, you can consider that this naming is a convention. You can see the corresponding page (reproduced in Figure 4-1) by browsing to the following URL: 50 46 51 http://localhost/ myapp_dev.php/mymodule/index47 http://localhost/frontend_dev.php/content/index 52 48 53 49 The default `index` action will not be used in this chapter, so you can remove the `executeIndex()` method from the `actions.class.php` file, and delete the `indexSuccess.php` file from the `templates/` directory. … … 67 63 ### Adding an Action 68 64 69 The "Hello, world!" page will be accessible through a ` myAction` action. To create it, just add an `executeMyAction` method to the `mymoduleActions` class, as shown in Listing 4-2.65 The "Hello, world!" page will be accessible through a `show` action. To create it, just add an `executeShow` method to the `contentActions` class, as shown in Listing 4-2. 70 66 71 67 Listing 4-2 - Adding an Action Is Like Adding an Execute Method to the Action Class … … 74 70 <?php 75 71 76 class mymoduleActions extends sfActions77 { 78 public function execute MyAction()79 { 80 } 81 } 82 83 The name of the action method is always `execute ``Xxx``()`, where the second part of the name is the action name with the first letter capitalized.72 class contentActions extends sfActions 73 { 74 public function executeShow() 75 { 76 } 77 } 78 79 The name of the action method is always `executeXxx()`, where the second part of the name is the action name with the first letter capitalized. 84 80 85 81 Now, if you request the following URL: 86 82 87 http://localhost/ myapp_dev.php/mymodule/myAction88 89 symfony will complain that the ` myActionSuccess.php` template is missing. That's normal; in symfony, a page is always made of an action and a template.83 http://localhost/frontend_dev.php/content/show 84 85 symfony will complain that the `showSuccess.php` template is missing. That's normal; in symfony, a page is always made of an action and a template. 90 86 91 87 >**CAUTION** 92 >URLs (not domain names) are case-sensitive, and so is symfony (even though the method names are case-insensitive in PHP). This means that if you add an `execute myaction()` method, or an `executeMyaction()`, and then you call `myAction` with the browser, symfony will return a 404 error.88 >URLs (not domain names) are case-sensitive, and so is symfony (even though the method names are case-insensitive in PHP). This means that if you add an `executeshow()` method, or an `executeShow()`, and then you call `show` with the browser, symfony will return a 404 error. 93 89 94 90 - … … 99 95 >Symfony contains a routing system that allows you to have a complete separation between the actual action name and the form of the URL needed to call it. This allows for custom formatting of the URL as if it were part of the response. You are no longer limited by the file structure nor by the request parameters; the URL for an action can look like the phrase you want. For instance, the call to the index action of a module called article usually looks like this: 100 96 > 101 > http://localhost/ myapp_dev.php/article/index?id=12397 > http://localhost/frontend_dev.php/article/index?id=123 102 98 > 103 99 >This URL retrieves a given article from a database. In this example, it retrieves an article (with `id=123`) in the Europe section that specifically discusses finance in France. But the URL can be written in a completely different way with a simple change in the `routing.yml` configuration file: … … 111 107 >Symfony knows how to parse and generate smart URLs for the user. The routing system automatically peels the request parameters from a smart URL and makes them available to the action. It also formats the hyperlinks included in the response so that they look "smart." You will learn more about this feature in Chapter 9. 112 108 > 113 >Overall, this means that the way you name the actions of your applications should not be influenced by the way the URL used to call them should look, but by the actions' functions in the application. An action name explains what the action actually does, and it 's often a verb in the infinitive form (like `show`, `list`, `edit`, and so on). Action names can be made totally invisible to the end user, so don't hesitate to use explicit action names (like `listByName` or `showWithComments`). You will economize on code comments to explain your action function, plus the code will be much easier to read.109 >Overall, this means that the way you name the actions of your applications should not be influenced by the way the URL used to call them should look, but by the actions' functions in the application. An action name explains what the action actually does, and it is often a verb in the infinitive form (like `show`, `list`, `edit`, and so on). Action names can be made totally invisible to the end user, so don't hesitate to use explicit action names (like `listByName` or `showWithComments`). You will economize on code comments to explain your action function, plus the code will be much easier to read. 114 110 115 111 ### Adding a Template 116 112 117 The action expects a template to render itself. A template is a file located in the `templates/` directory of a module, named by the action and the action termination. The default action termination is a "success," so the template file to be created for the ` myAction` action is to be called `myActionSuccess.php`.113 The action expects a template to render itself. A template is a file located in the `templates/` directory of a module, named by the action and the action termination. The default action termination is a "success," so the template file to be created for the `show` action is to be called `showSuccess.php`. 118 114 119 115 Templates are supposed to contain only presentational code, so keep as little PHP code in them as possible. As a matter of fact, a page displaying "Hello, world!" can have a template as simple as the one in Listing 4-3. 120 116 121 Listing 4-3 - The ` mymodule/templates/myActionSuccess.php` Template117 Listing 4-3 - The `content/templates/showSuccess.php` Template 122 118 123 119 [php] … … 159 155 <?php 160 156 161 class mymoduleActions extends sfActions162 { 163 public function execute MyAction()157 class contentActions extends sfActions 158 { 159 public function executeShow() 164 160 { 165 161 $today = getdate(); … … 173 169 <p>Hello, world!</p> 174 170 <?php if ($hour >= 18): ?> 175 <p>Or should I say good evening? It's already <?php echo $hour ?>.</p> 176 <?php endif; ?> 177 178 >**NOTE** 179 >The template already has access to a few pieces of data without the need of any variable setup in the action. Every template can call methods of the `$sf_context`, `$sf_request`, `$sf_params`, and `$sf_user` objects. They contain data related to the current context, request, request parameters, and session. You will soon learn how to use them efficiently. 180 181 Gathering Information from the User with Forms 182 ---------------------------------------------- 183 184 Forms are a good way to get information from the user. Writing form and form elements in HTML can sometimes be cumbersome, especially when you want to be XHTML-compliant. You could include form elements in symfony templates the usual way, as shown in Listing 4-8, but symfony provides helpers that make this task easier. 185 186 Listing 4-8 - Templates Can Include Usual HTML Code 171 <p>Or should I say good evening? It is already <?php echo $hour ?>.</p> 172 <?php endif; ?> 173 174 Note that the use of the short opening tags (`<?=`, equivalent to `<?php echo`) is not recommended for professional web applications, since your production web server may be able to understand more than one scripting language and consequently get confused. Besides, the short opening tags do not work with the default PHP configuration and need server tweaking to be activated. Ultimately, when you have to deal with XML and validation, it falls short because `<?` has a special meaning in XML. 175 176 >**NOTE** 177 >The template already has access to a few pieces of data without the need of any variable setup in the action. Every template can call methods of the `$sf_request`, `$sf_params`, `$sf_response`, and `$sf_user` objects. They contain data related to the current request, request parameters, response, and session. You will soon learn how to use them efficiently. 178 179 Linking to Another Action 180 ------------------------- 181 182 You already know that there is a total decoupling between an action name and the URL used to call it. So if you create a link to `update` in a template as in Listing 4-10, it will only work with the default routing. If you later decide to change the way the URLs look, then you will need to review all templates to change the hyperlinks. 183 184 Listing 4-10 - Hyperlinks, the Classic Way 185 186 [php] 187 <a href="/frontend_dev.php/content/update?name=anonymous"> 188 I never say my name 189 </a> 190 191 To avoid this hassle, you should always use the `link_to()` helper to create hyperlinks to your application's actions. And if you only want the generate the URL part, the `url_for()` is the helper you're looking for. 192 193 A helper is a PHP function defined by symfony that is meant to be used within templates. It outputs some HTML code and is faster to use than writing the actual HTML code by yourself. Listing 4-11 demonstrates the use of the hyperlink helpers. 194 195 Listing 4-11 - The `link_to()`, and `url_for()` Helpers 187 196 188 197 [php] 189 198 <p>Hello, world!</p> 190 199 <?php if ($hour >= 18): ?> 191 <p>Or should I say good evening? It 's already <?php echo $hour ?>.</p>192 <?php endif; ?> 193 <form method="post" target="/myapp_dev.php/mymodule/anotherAction">200 <p>Or should I say good evening? It is already <?php echo $hour ?>.</p> 201 <?php endif; ?> 202 <form method="post" action="<?php echo url_for('content/update') ?>"> 194 203 <label for="name">What is your name?</label> 195 204 <input type="text" name="name" id="name" value="" /> 196 205 <input type="submit" value="Ok" /> 206 <?php echo link_to('I never say my name','content/update?name=anonymous') ?> 197 207 </form> 198 208 199 A helper is a PHP function defined by symfony that is meant to be used within templates. It outputs some HTML code and is faster to use than writing the actual HTML code by yourself. Using symfony helpers, you can have the same result as in Listing 4-8 with the code shown in Listing 4-9.200 201 Listing 4-9 - It Is Faster and Easier to Use Helpers Than to Use HTML Tags202 203 [php]204 <p>Hello, world!</p>205 <?php if ($hour >= 18): ?>206 <p>Or should I say good evening? It's already <?php echo $hour ?>.</p>207 <?php endif; ?>208 <?php echo form_tag('mymodule/anotherAction') ?>209 <?php echo label_for('name', 'What is your name?') ?>210 <?php echo input_tag('name') ?>211 <?php echo submit_tag('Ok') ?>212 </form>213 214 >**SIDEBAR**215 >Helpers are here to help you216 >217 >If, in the example in Listing 4-9, you think the helper version is not really faster to write than the HTML one, consider this one:218 >219 > [php]220 > <?php221 > $card_list = array(222 > 'VISA' => 'Visa',223 > 'MAST' => 'MasterCard',224 > 'AMEX' => 'American Express',225 > 'DISC' => 'Discover');226 > echo select_tag('cc_type', options_for_select($card_list, 'AMEX'));227 > ?>228 >229 >This outputs the following HTML:230 >231 > [php]232 > <select name="cc_type" id="cc_type">233 > <option value="VISA">Visa</option>234 > <option value="MAST">MasterCard</option>235 > <option value="AMEX" selected="selected">American Express</option>236 > <option value="DISC">Discover</option>237 > </select>238 >239 >The benefit of helpers in templates is raw speed of coding, clarity of code, and concision. The only price to pay is the time to learn them, which will end when you finish this book, and the time to write <?php echo ?>, for which you should already have a shortcut in your favorite text editor. So you could not use the symfony helpers in templates and write HTML the way you always did, but this would be a great loss and much less fun.240 241 Note that the use of the short opening tags (`<?=`, equivalent to `<?php echo`) is not recommended for professional web applications, since your production web server may be able to understand more than one scripting language and consequently get confused. Besides, the short opening tags do not work with the default PHP configuration and need server tweaking to be activated. Ultimately, when you have to deal with XML and validation, it falls short because `<?` has a special meaning in XML.242 243 Form manipulation deserves a whole chapter of its own, since symfony provides many tools, mostly helpers, to make it easier. You will learn more about these helpers in Chapter 10.244 245 Linking to Another Action246 -------------------------247 248 You already know that there is a total decoupling between an action name and the URL used to call it. So if you create a link to `anotherAction` in a template as in Listing 4-10, it will only work with the default routing. If you later decide to change the way the URLs look, then you will need to review all templates to change the hyperlinks.249 250 Listing 4-10 - Hyperlinks, the Classic Way251 252 [php]253 <a href="/myapp_dev.php/mymodule/anotherAction?name=anonymous">254 I never say my name255 </a>256 257 To avoid this hassle, you should always use the `link_to()` helper to create hyperlinks to your application's actions. Listing 4-11 demonstrates the use of the hyperlink helper.258 259 Listing 4-11 - The `link_to()` Helper260 261 [php]262 <p>Hello, world!</p>263 <?php if ($hour >= 18): ?>264 <p>Or should I say good evening? It's already <?php echo $hour ?>.</p>265 <?php endif; ?>266 <?php echo form_tag('mymodule/anotherAction') ?>267 <?php echo label_for('name', 'What is your name?') ?>268 <?php echo input_tag('name') ?>269 <?php echo submit_tag('Ok') ?>270 <?php echo link_to('I never say my name','mymodule/anotherAction?name=anonymous') ?>271 </form>272 273 209 The resulting HTML will be the same as previously, except that when you change your routing rules, all the templates will behave correctly and reformat the URLs accordingly. 274 210 211 Form manipulation deserves a whole chapter of its own, since symfony provides many tools to make it even easier. You will learn more about these helpers in Chapter 10. 212 275 213 The `link_to()` helper, like many other helpers, accepts another argument for special options and additional tag attributes. Listing 4-12 shows an example of an option argument and the resulting HTML. The option argument is either an associative array or a simple string showing `key=value` couples separated by blanks. 276 214 … … 279 217 [php] 280 218 // Option argument as an associative array 281 <?php echo link_to('I never say my name', ' mymodule/anotherAction?name=anonymous',219 <?php echo link_to('I never say my name', 'content/update?name=anonymous', 282 220 array( 283 221 'class' => 'special_link', … … 287 225 288 226 // Option argument as a string 289 <?php echo link_to('I never say my name', ' mymodule/anotherAction?name=anonymous',227 <?php echo link_to('I never say my name', 'content/update?name=anonymous', 290 228 'class=special_link confirm=Are you sure? absolute=true') ?> 291 229 292 230 // Both calls output the same 293 231 => <a class="special_link" onclick="return confirm('Are you sure?');" 294 href="http://localhost/ myapp_dev.php/mymodule/anotherAction/name/anonymous">232 href="http://localhost/frontend_dev.php/content/update/name/anonymous"> 295 233 I never say my name</a> 296 234 … … 300 238 >Because it requires an additional parsing and transformation, the string syntax is a little slower than the array syntax. 301 239 302 Like the formhelpers, the link helpers are numerous and have many options. Chapter 9 will describe them in detail.240 Like all symfony helpers, the link helpers are numerous and have many options. Chapter 9 will describe them in detail. 303 241 304 242 Getting Information from the Request 305 243 ------------------------------------ 306 244 307 Whether the user sends information via a form (usually in a POST request) or via the URL (GET request), you can retrieve the related data from the action with the `get RequestParameter()` method of the `sfActions` object. Listing 4-13 shows how, in `anotherAction`, you retrieve the value of the `name` parameter.245 Whether the user sends information via a form (usually in a POST request) or via the URL (GET request), you can retrieve the related data from the action with the `getParameter()` method of the `sfRequest` object. Listing 4-13 shows how, in `update`, you retrieve the value of the `name` parameter. 308 246 309 247 Listing 4-13 - Getting Data from the Request Parameter in the Action … … 312 250 <?php 313 251 314 class mymoduleActions extends sfActions 315 { 316 ... 317 318 public function executeAnotherAction() 319 { 320 $this->name = $this->getRequestParameter('name'); 321 } 322 } 323 324 If the data manipulation is simple, you don't even need to use the action to retrieve the request parameters. The template has access to an object called `$sf_params`, which offers a `get`() method to retrieve the request parameters, just like the getRequestParameter() in the action. 325 326 If `executeAnotherAction()` were empty, Listing 4-14 shows how the `anotherActionSuccess.php` template would retrieve the same `name` parameter. 252 class contentActions extends sfActions 253 { 254 // ... 255 256 public function executeUpdate($request) 257 { 258 $this->name = $request->getParameter('name'); 259 } 260 } 261 262 As a convenience, all `executeXxx()` methods take the current `sfRequest` object as its first argument. 263 264 If the data manipulation is simple, you don't even need to use the action to retrieve the request parameters. The template has access to an object called `$sf_params`, which offers a `get`() method to retrieve the request parameters, just like the `getParameter()` in the action. 265 266 If `executeUpdate()` were empty, Listing 4-14 shows how the `updateSuccess.php` template would retrieve the same `name` parameter. 327 267 328 268 Listing 4-14 - Getting Data from the Request Parameter Directly in the Template … … 355 295 In symfony, pages are composed of an action (a method in the `actions/actions.class.php` file prefixed with `execute`) and a template (a file in the `templates/` directory, usually ending with `Success.php`). They are grouped in modules, according to their function in the application. Writing templates is facilitated by helpers, which are functions provided by symfony that return HTML code. And you need to think of the URL as a part of the response, which can be formatted as needed, so you should refrain from using any direct reference to the URL in action naming or request parameter retrieval. 356 296 357 Once you know these basic principles, you can already write a whole web application with symfony. But it would take you way too long, since almost every task you will have to achieve during the course of the application development is facilitated one way or another by some symfony feature . .. which is why the book doesn't stop now.297 Once you know these basic principles, you can already write a whole web application with symfony. But it would take you way too long, since almost every task you will have to achieve during the course of the application development is facilitated one way or another by some symfony feature... which is why the book doesn't stop now. doc/trunk/book/05-Configuring-Symfony.txt
r4908 r8376 155 155 >And if you don't like YAML 156 156 > 157 >YAML is just an interface to define settings to be used by PHP code, so the configuration defined in YAML files ends up being transformed into PHP. After browsing an application, check its cached configuration (in `cache/ myapp/dev/config/`, for instance). You will see the PHP files corresponding to your YAML configuration. You will learn more about the configuration cache later in this chapter.157 >YAML is just an interface to define settings to be used by PHP code, so the configuration defined in YAML files ends up being transformed into PHP. After browsing an application, check its cached configuration (in `cache/frontend/dev/config/`, for instance). You will see the PHP files corresponding to your YAML configuration. You will learn more about the configuration cache later in this chapter. 158 158 > 159 159 >The good news is that if you don't want to use YAML files, you can still do what the configuration files do by hand, in PHP or via another format (XML, INI, and so on). Throughout this book, you will meet alternative ways to define configuration without YAML, and you will even learn to replace the symfony configuration handlers (in Chapter 19). If you use them wisely, these tricks will enable you to bypass configuration files or define your own configuration format. … … 225 225 <?php 226 226 227 define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/..')); 228 define('SF_APP', 'myapp'); 229 define('SF_ENVIRONMENT', 'prod'); 230 define('SF_DEBUG', false); 231