Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 42 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
42
Dung lượng
750,02 KB
Nội dung
CHAPTER 3 ■ WRITING CONTROLLERS USING ZEND_CONTROLLER 66 ) )); $application->bootstrap()->run(); The updated index.php file contains new routing information by first fetching an instance of Zend_Controller_Front, then fetching its router, and finally adding a new route using addRoute(). The addRoute() method accepts two parameters: an identifier for the route and a Zend_Controller_Router_Route object. Save the file and load the URL http://localhost/artist/store, which then loads ArtistController::artistaffiliatecontentAction(). So how does it work? When a URL is fetched within an application, the front controller looks at the URL and then looks at the declared routes to determine whether there are any URL patterns that apply to the user’s request. If the URL matches one of the patterns specified by the routes, the request loads the controller- action pair specified in the Zend_Controller_Router_Route second parameter. On the other hand, if the URL pattern does not match any of the routes, the user is shown an error message. With the changes saved, let’s create a new view for the artist store. Create the artistaffiliatecontent.phtml file with the XHTML shown in Listing 3-8, and save the file in the application/views/scripts/artist/ directory. Bring up the URL in your browser: http://localhost/artist/store. Listing 3-8. artistaffiliatecontent.phtml <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>LoudBite.com – Artist Products</title> </head> <body> Product #1 - Test </body> </html> You know how the controller handles the user’s requests and how to mask the URLs to give them a more user-friendly pattern. Now let’s see how to pass variables through the URL. Passing Parameters with Route You might sometimes implement code that retrieves parameter information from a query string such as http://localhost/artists?name=metallica or http://localhost/user?username=armando. Using Zend_Controller_Router, you can allow users to use a much simpler URL such as http://localhost/artist/Metallica and have the application know that the last item in the URL path is the artist name or data you need. To implement this feature, you need to declare the variable within the Zend_Controller_Router_Route object. To do so, initialize the name of the variable in the first parameter of the object using : followed by the name of the variable. The variable must contain only PHP-acceptable characters. To fetch the content within the controller-action, you can either use $_GET['name of variable'] or the Zend_Controller Request object. Download at Boykma.Com CHAPTER 3 ■ WRITING CONTROLLERS USING ZEND_CONTROLLER 67 Listing 3-9. Setting variables in route Zend_Controller_Router_Route("artist/:artistname", array ("artistname" => "The Smiths", "controller" => "artist", "action" => "profile" )) The snippet of code shown in Listing 3-9 initializes a new variable, artistname, and sets its default value to The Smiths. Once this route is added, the user will able to load the URL http://localhost/artist/metallica or http://localhost/artist/the beatles. Let’s now add this route into index.php, as shown in Listing 3-10. Listing 3-10. index.php <?php //Define path to application directory defined('APPLICATION_PATH') || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/ /application')); // Define application environment defined('APPLICATION_ENV') || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production')); // Ensure library/ is on include_path set_include_path(implode(PATH_SEPARATOR, array( realpath(APPLICATION_PATH . '/ /library'), get_include_path(), ))); /** Zend_Application */ require_once 'Zend/Application.php'; // Create application, bootstrap, and run $application = new Zend_Application( APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini' ); /** Routing Info **/ $FrontController = Zend_Controller_Front::getInstance(); $Router = $FrontController->getRouter(); $Router->addRoute("artistprofile", new Zend_Controller_Router_Route( Download at Boykma.Com CHAPTER 3 ■ WRITING CONTROLLERS USING ZEND_CONTROLLER 68 "artist/:artistname", array ("artistname" => "The Smiths", "controller" => "artist", "action" => "profile" ))); $Router->addRoute("artiststore", new Zend_Controller_Router_Route( "artist/store", array ("controller" => "artist", "action" => "artistaffiliatecontent" ))); $application->bootstrap()->run(); Because the ArtistController.php file currently does not contain a profileAction method to support the new route, create the action, as shown in Listing 3-11. Listing 3-11. ArtistController::profileAction method /** * Artist Profile * */ public function profileAction() { } You’ll now look at how to fetch these variables along with other user-defined data using the Request object. Request Object Going back to the MVC life cycle, after the controller finishes processing with no errors, it initializes the user interface (UI) that the user will see, otherwise known as the view. Because the view is a critical component for the controller, the controller automatically creates three objects for immediate use: • ViewRenderer • Request • Response The Request object is covered in this section (you’ll look at the ViewRenderer and the Response object in Chapter 4). The Request object handles all incoming user data or any data sent from the user’s browser to the application code. This data is always in the form of a POST submission, query submitted data, or raw header data. Download at Boykma.Com CHAPTER 3 ■ WRITING CONTROLLERS USING ZEND_CONTROLLER 69 Query data comes in the form of a URL such as http://localhost/account?u=armando, where u=armando is the data you want to process. POST data is form-submitted content. The request object allows you to fetch this data and manipulate it within the code. You’ll expand on the sign-up form and add the artist form for this example. Let’s start with the AccountController. You already have the newAction() method, which deals with requests for the sign-up form, but you need an action to process any incoming form submissions. This requires an action in the AccountController.php file, so you’ll be using the successAction() method, as shown in Listing 3-12. You want to learn how Zend Framework handles incoming data, so you’ll fetch all incoming parameters. Listing 3-12. AccountController.php – updated successAction /** * Process the account form. * */ public function successAction() { $email = $this->_request->getParam('email'); $username = $this->_request->getParam('username'); $password = $this->_request->getParam('password'); //Save the user into the system. } As you can tell from the preceding code, you added a few lines into the successAction() method. The new lines of code allows you to capture all incoming user data by using the request object’s getParam() method. Here you capture three parameters from an XHTML form you will create in Chapter 4, containing three form input fields for the new.ptml page and store the data inside three variables: $email, $username, and $password. At the moment you won’t be doing much with this data, but it’s nice to have a foundation that allows you to successfully capture user data. Expanding on the getParam() method, it accepts a parameter, which is the name of the parameter you want to capture. The form input field name values specified were email password and username. These unique identifiers are the parameters for the getParam() function. Easy, right? Yes, but there is a big security risk using this method, and the best way to understand why is to analyze how Zend Framework treats superglobal data. Superglobal Data in Zend Framework You’ve used superglobal variables because they are part of PHP. COOKIE, SERVER, ENV, GET, and POST are the types of superglobal variables that Zend Framework uses and these are also the variables that the request object fetches. Zend Framework uses a set way to capture these variables. Following is the order in which Zend Framework captures these variables: Download at Boykma.Com CHAPTER 3 ■ WRITING CONTROLLERS USING ZEND_CONTROLLER 70 1. GET 2. POST 3. COOKIE 4. SERVER 5. ENV Because getParam() does not distinguish whether you want to fetch POST data or GET data, a malicious user can easily change any POST data by modifying the URL to pass in a GET value. To counteract this behavior, Zend Framework created a list of getters (see Table 3-1). Request Object’s Getters Suppose that you attempted the old tried-and-true method of creating a simple form for your users and you created that millionth form $_POST code on your PHP script. Let’s use the secure Zend Framework getter now by updating AccountController successAction(), as shown in Listing 3-13. Listing 3-13. AccountController.php <?php /** * Account Controller * */ class AccountController extends Zend_Controller_Action { public function init() { /* Initialize action controller here */ } public function indexAction() { // action body } /** * Process the account form. * */ public function successAction() { Download at Boykma.Com CHAPTER 3 ■ WRITING CONTROLLERS USING ZEND_CONTROLLER 71 $email = $this->_request->getPost("email"); $username = $this->_request->getPost("username"); $password = $this->_request->getPost("password"); //Save the user into the system. } /** * Display the form for signing up. * */ public function newAction() { } /** * Activate Account. Used once the user * receives a welcome email and decides to authenticate * their account. * */ public function activateAction() { } } In this example, successAction() takes the user’s information that was previously entered in the form using the getPost() method, which retrieves only POST data. The getPost() method allows you to fetch only data passed in using a POST request and nothing else. This is different from the getParam() method that allows users to use POST or query data. But sometimes you need to have query data such as account validation or a parameter that helps you fetch paginated data. Processing a GET Submission POST data is nice, but what if you require the user to pass in a variable string through the URL? A good example is a user authenticating the account after signing up as a new user by clicking a link in an e-mail message (for example, http://localhost/account/activate?email=test@test.com or a user paginating through a list of images in your search result that uses the URL http://localhost/account/results?x=20 to determine which result index to start from). Apart from getParam(), how do you retrieve those values? For this example, you’ll update the activateAction() method in the AccountController.php file, as shown in Listing 3-14. The action will retrieve the e-mail address that needs to be activated from the requested URL clicked by the user. You’ll fetch the data, but not fully activate the account just yet. Download at Boykma.Com CHAPTER 3 ■ WRITING CONTROLLERS USING ZEND_CONTROLLER 72 Listing 3-14. AccountController.php: Using getQuery <?php /** * Account Controller * */ class AccountController extends Zend_Controller_Action { public function init() { /* Initialize action controller here */ } public function indexAction() { // action body } /** * Process the account form. * */ public function successAction() { $email = $this->_request->getPost("email"); $username = $this->_request->getPost("username"); $password = $this->_request->getPost("password"); //Save the user into the system. } /** * Display the form for signing up. * */ public function newAction() { } /** * Activate Account. Used once the user * receives a welcome email and decides to authenticate Download at Boykma.Com CHAPTER 3 ■ WRITING CONTROLLERS USING ZEND_CONTROLLER 73 * their account. * */ public function activateAction() { //Fetch the email to update from the query param 'email' $emailToActivate = $this->_request->getQuery("email"); //Check if the email exists //Activate the Account. } } Compare the POST and GET examples; there isn’t much difference. In both examples, you use the request object, but in this example you use the getQuery() method to retrieve all incoming query variables. Other Request Object Features The request object doesn’t stop there when it comes to fetching user data. It also allows you to fetch all raw POST and header information. Take a look at Table 3-1 for more information on the type of operations the request object can handle. Table 3-1. Request Object Operations Function What Does It Do? What Does It Return? getParam(String key) Retrieves an individual parameter to be accessible by the action. Returns the value for the parameter key specified. getParams() Retrieves multiple parameters to be accessible by the action. Returns an associative array of key/value pairs for multiple parameters of a request object. getPost(String key) Retrieves an individual parameter to be accessible by the action. Returns the value for the parameter key specified. getQuery(String key) Retrieves an individual GET parameter to be accessible by the action. Returns the value for the parameter key specified. Zend Request Type Checkers Besides allowing you to retrieve information sent to you by a user’s request or a process, the request object can also determine the type of request that was made. This is great if you want to validate whether the request was a POST request or an Ajax request. Using request-type checkers reduces the chances of Download at Boykma.Com CHAPTER 3 ■ WRITING CONTROLLERS USING ZEND_CONTROLLER 74 malicious users trying to manipulate POST variables with GET variables or send a POST to a process when your code expects an Ajax XmlHttpRequest call. Checking Whether the Request Is a POST Zend Framework’s request object comes equipped with the method isPost() that you can use to test for POST data, as shown in Listing 3-15. Listing 3-15. AccountController.php: Using isPost() <?php /** * Account Controller * */ class AccountController extends Zend_Controller_Action { public function init() { /* Initialize action controller here */ } public function indexAction() { // action body } /** * Process the account form. * */ public function successAction() { //Check if the submitted data is POST type if($this->_request->isPost()){ $email = $this->_request->getPost("email"); $username = $this->_request->getPost("username"); $password = $this->_request->getPost("password"); //Save the user into the system. }else{ throw new Exception("Whoops. Wrong way of submitting your information."); } Download at Boykma.Com CHAPTER 3 ■ WRITING CONTROLLERS USING ZEND_CONTROLLER 75 } /** * Display the form for signing up. * */ public function newAction() { } /** * Activate Account. Used once the user * receives a welcome email and decides to authenticate * their account. * */ public function activateAction() { //Fetch the email to update from the query param 'email' $emailToActivate = $this->_request->getQuery("email"); //Check if the email exists //Activate the Account. } } Listing 3-15 expands the successAction() method to validate that the incoming request was a POST type. The important section in this example is the if statement. Here you use the default request object and its isPost() method. If the incoming request is not a POST type, the user sees an error message: “Whoops. Wrong way of submitting your information.” The script then stops executing. Checking for a GET Request Checking for a GET request type is straightforward and requires you to change only the if statement to read as follows: if($this->_request->isGet()) The new function that uses a GET request type looks like this: //Action #1 - Sign up for an account form. public function successAction(){ //Check if the submitted data is GET type Download at Boykma.Com [...]... internal Zend Framework error message using getMessage(), as you do in Listing 3- 22, or you can display the steps that Zend Framework took to get to the current error using getTrace() The following line is required if you want to display the error in the phtml file by making the exception object available there: $this->view->exception = $exception; Take a look at the functions shown in Table 3- 3; Zend Framework. .. of useful information You can use these functions to display the information stored in the exception object Table 3- 3 Zend_ Exception Operations Method Description Return Type getMessage Returns Zend Framework created error message String getTrace Returns a complete flow of the way Zend Framework arrived at the error Array getLine Returns the line where the error was located String getTraceAsString... user to fill out a form and submit, as shown in Figure 3- 3, the application will initialize the submitted data inside the action, but will save the information to a database inside a model (refer to Figure 3- 4) Figure 3- 5 expands on Figure 3- 3, in which you took a look at how the user’s event triggers the appropriate action in a controller In Figure 3- 5, after the user has successfully submitted the form... pair array (see Listing 3- 20) Listing 3- 20 Updated Front Controller $FrontController = Zend_ Controller_Front::getInstance(); $plugin = new Zend_ Controller_Plugin_ErrorHandler(); $plugin->setErrorHandler(array("controller" => 'ApplicationError', "action" => 'index')); $FrontController->registerPlugin($plugin); Using Error Variables in the View Another exciting feature of Zend Framework error handling... across, as shown in Listing 3- 17 Listing 3- 17 Error Handler Controller: ErrorController.php ... processed using Zend Form You’ll go through the majority of form elements supported by Zend Framework_ such as text fields, password fields, select menus, radio buttons, and check boxes You’ll then apply each form field into the LoudBite application Once you’re done with the Zend_ Form and Zend_ Form_Element objects, you’ll move into filtering and validating data that users enter into the newly created Zend_ Form... ApplicationErrorController instead of errorAction This is all done using the Zend_ Controller_Plugin_ErrorHandler object’s setErrorHandlerController() and setErrorHandlerAction() setters (see Listing 3- 19) Listing 3- 19 Updated FrontController in index.php: Using Setters $FrontController = Zend_ Controller_Front::getInstance(); $plugin = new Zend_ Controller_Plugin_ErrorHandler(); $plugin->setErrorHandlerController("ApplicationError");... your teeth into a little asynchronous calling You pop open that browser and start looking up for a nice Ajax framework After you choose your framework, you might wonder how you can stitch the Ajax calls to Zend Framework I won’t cover the setup of an Ajax call because there are too many good Ajax frameworks out there: jQuery, Prototype, Scriptaculous, and Dojo So I will cover only the back-end script... chapter took Zend_ Controller from its architectural foundation to the way the controller itself lives This chapter is an essential step to understanding not only the MVC pattern but also MVC Zend Framework applications The following topics were discussed: • Understanding the MVC pattern and its benefits • Constructing a Zend_ Controller using best practices • Adding actions to a controller 83 Download... action that is called automatically by Zend Framework every time the user encounters an error The HTML file contains the message that you want to display to users when they encounter an error In this case, it is a simple message Extending Error Handling Zend Framework allows you to take full control of error handling and drill down into key messages created by the framework for debugging purposes If you . shown in Table 3- 3; Zend Framework provides you with a lot of useful information. You can use these functions to display the information stored in the exception object. Table 3- 3. Zend_ Exception. on your PHP script. Let’s use the secure Zend Framework getter now by updating AccountController successAction(), as shown in Listing 3- 13. Listing 3- 13. AccountController.php <?php /** *. that Zend Framework uses and these are also the variables that the request object fetches. Zend Framework uses a set way to capture these variables. Following is the order in which Zend Framework