Expert PHP 5 Tools phần 9 pdf

46 332 0
Expert PHP 5 Tools phần 9 pdf

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Chapter 8 [ 353 ] The copy task takes care of moving the Config.php template to the includes/ classes/ directory where the application expects it to be. However, there are a couple of extra steps involved in this task that warrant a second look. There are two sub-tags that are being used inside the copy task. First, the filterchain task allows you to process the les that are being copied. In our case, we are using the expandproperties task to replace all placeholders with properties. Second, the fileset task allows us to construct a list of les by including or excluding individual les based on various criteria, such as regular expressions that match the path or name of the les. For our purposes, the list consists of only a single le, Config.php, which we include by name. Maintenance page At this point, we have completed all preliminary steps for upgrading the site. For the actions, we want to ensure that normal trafc to the site cannot interfere. Simultaneously, it is now necessary to let the users know that the site will be temporarily unavailable by redirecting all trafc to a maintenance page that informs the user that the site is temporarily unavailable due to maintenance. I have such a page called maintenance.html in the root of the publicly accessible directory, htdocs. I use Apache as my web server, which supports per-directory conguration les, typically called .htaccess les. For this to work, you have to make sure that .htaccess les are enabled. The following code also requires the mod_rewrite module to be enabled in Apache, which we use to change request URLs and redirect the user's browser. Basically, we are creating a local Apache conguration le that uses mod_rewrite to temporarily redirect all requests to the maintenance.html page. <target name="disp-maint" description="Export the site's files from subversion to the local target directory."> <! check whether there already is an .htaccess file > <available file="${site.root}/htdocs/.htaccess" property="htaccess_exists" type="file" /> <if> <equals arg1="${htaccess_exists}" arg2="true" /> <then> <! .htaccess file exists; move/rename it > <move file="${site.root}/htdocs/.htaccess" tofile="${site.home}/htdocs/.htaccess.bck" overwrite="false" /> </then> </if> <! new .htaccess file for maintenance screen > <echo file="${site.root}/htdocs/.htaccess" append="false"> Download from Wow! eBook www.WoweBook.com Deploying Applications [ 354 ] Options +FollowSymlinks RewriteEngine on RewriteCond %{REQUEST_URI} !/maintenance.html$ RewriteCond %{REMOTE_HOST} !^127\.0\.0\.1 RewriteRule $ /maintenance.html [R=302,L] </echo> </target> Rather than just create the .htaccess le, however, the code rst checks whether such a le already exists. If so, it renames the existing le using the move task. Then we use the echo task with the le attribute to write the necessary Apache conguration directives to the newly created .htaccess le. Database backup As we have disabled regular trafc to the site, we can be assured that the underlying database is not being accessed anymore. If the site you are deploying has any automated jobs that access the database, you will most likely want to tweak the previous target to temporarily disable those jobs as well. It is now time to back up the database. Even though the tool we are using for database migrations supports incremental upgrades and downgrades, it is common practice to always create a complete backup of the database whenever anything changes. Hopefully you have a routine that backs up the database along with the rest of the site anyway. The following listing takes care of the database backup: <target name="backup-db" description="Backup the database before upgrade."> <! was the database password given in the properties file? > <if> <not> <isset property="db.password" /> </not> <then> <! prompt the user for the database password > <input propertyname="db.password" promptChar=":">Enter password for user ${db.user} for database ${db.name}</input> </then> </if> <! execute external command mysqldump to backup database > <exec command="${extern.mysqldump} quick password=${db.password} user=${db.user} ${db.name} > Download from Wow! eBook www.WoweBook.com Chapter 8 [ 355 ] ${db.name}.${DSTAMP}${TSTAMP}.sql" dir="${db.backup.dir}" escape="false" /> <! compress the DB dump file > <zip destfile="${db.backup.dir}/${db.name}.${DSTAMP}${TSTAMP}.sql.zip"> <fileset dir="${db.backup.dir}"> <include name="${db.name}.${DSTAMP}${TSTAMP}.sql" /> </fileset> </zip> <! delete the original DB dump file to save space > <delete file="${db.backup.dir}/${db.name}.${DSTAMP}${TSTAMP}.sql" /> </target> We start by checking whether the database password was provided in the properties le. If not, we interactively prompt the user to enter it from the command line. This logic should appear familiar to you because it is the same thing we did for getting the Subversion password. We then use the exec task to run an external command, namely the mysqldump utility to export the schema and data to a text le. This text le is a complete snapshot of the database and can be used to reset the database to exactly the state it was in when the snapshot was created. Once again we are incorporating the timestamp into the name of the le so we know exactly when it was created. The command attribute of the exec task is the command line that will be executed after changing the working directory to the path specied in the dir attribute. The escape attribute is a Boolean that determines whether shell meta characters will be escaped before executing the command. Please consult the manual for additional attributes supported by the exec task. Database dump les are just text les and as such ideal targets for saving disk space by compressing their content. Luckily, Phing provides a task for compressing les using the zip algorithm. Similar to the copy task we saw earlier, the zip task contains a fileset tag to specify which les are to be included in the archive. In our case, we are compressing a single le. Lastly, after the database dump le has been compressed, we can delete the original (uncompressed) le using the delete task. Although the delete task supports several other attributes, the only one we are using here is the file attribute to indicate the le that is to be the target of the deletion. Download from Wow! eBook www.WoweBook.com Deploying Applications [ 356 ] One last note regarding database backups is that the directory we use to store the backups is one of those which we created in the create-skeleton target earlier. Database migrations After backing up the database, we can apply any changes to the schema and/or data. For such purposes, Phing provides the very handy dbdeploy task. The way dbdeploy works is that you create an individual le for any change to the database. In that le, you put the SQL needed to upgrade the database; as well as the SQL needed to downgrade the database again. The two sets of SQL are separated by this character sequence: //@UNDO. The name of the le should be descriptive of what it does. It also must start with an integer that indicates the order in which the individual migration les are to be processed. The lower numbered ones are executed before the higher ones. To keep track of which migrations have been applied, dbdeploy requires its own tracking: CREATE TABLE `changelog` ( `change_number` bigint(20) NOT NULL, `delta_set` varchar(10) NOT NULL, `start_dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `complete_dt` timestamp NULL DEFAULT NULL, `applied_by` varchar(100) NOT NULL, `description` varchar(500) NOT NULL, PRIMARY KEY (`change_number`,`delta_set`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; For example, to create a table called users, I created the following le: db/deltas/1-create-users.sql CREATE TABLE `users` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `login` varchar(50) NOT NULL, `password` varchar(100) NOT NULL, `email` varchar(100) DEFAULT ‘', `active` tinyint(1) NOT NULL DEFAULT ‘1', `date_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `date_added` timestamp NOT NULL DEFAULT ‘0000-00-00 00:00:00', PRIMARY KEY (`id`), UNIQUE KEY `unique_login` (`login`) ) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1; Download from Wow! eBook www.WoweBook.com Chapter 8 [ 357 ] //@UNDO DROP TABLE IF EXISTS `users`; The CREATE TABLE statement is the upgrade path and the DROP TABLE is the opposite action and thus provides us with the downgrade path. The dbdeploy task doesn't actually execute the SQL. It only creates it. That is why an exec task is required to execute the generated upgrade SQL via the MySQL command line client. Here is the target to upgrade the database: <target name="deploy-db" description="Runs the SQL migrations to update the DB schema and data."> <! load the dbdeploy task > <taskdef name="dbdeploy" classname="phing.tasks.ext.dbdeploy.DbDeployTask"/> <! generate SQL to upgrade the DB to the most recent migration > <dbdeploy url="mysql:host=${db.fqdn};dbname=${db.name}" userid="${db.user}" password="${db.password}" dir="${site.root}.${DSTAMP}${TSTAMP}/db/deltas" outputfile="${site.home}/build/db-upgrade- ${DSTAMP}${TSTAMP}.sql" undooutputfile="${site.home}/build/db-downgrade- ${DSTAMP}${TSTAMP}.sql" /> <! execute SQL using mysql command line client > <exec command="${extern.mysql} -h${db.fqdn} -u${db.user} - p${db.password} ${db.name} &lt; ${site.home}/build/db-upgrade- ${DSTAMP}${TSTAMP}.sql" dir="${site.home}/build" checkreturn="true" /> </target> Download from Wow! eBook www.WoweBook.com Deploying Applications [ 358 ] Going live We are almost there. We have checked out and modied the site, backed up and upgraded the database. All that is left is to make the actual switch from the previous version of the site to the one we just created. That is the job of the publish-site target in the following listing: <target name="publish-site" description="Activates new version of site and restarts Apache for all changes to take effect."> <! symlink in external library dependencies > <exec command="${extern.ln} -s ${zend_dir}" dir="${site.root}.${DSTAMP}${TSTAMP}/includes/libraries" escape="false <! delete symlink to currently active copy of the site > <delete file="${site.root}" /> <! symlink to newest version of site > <exec command="${extern.ln} -s ${site.fqdn}.${DSTAMP}${TSTAMP} ${site.fqdn}" dir="${site.home}" escape="false" /> <! restart the Apache web server gracefully for all changes to take effect: we are live now!!! > <exec command="${extern.sudo} ${extern.apachectl} graceful" escape="false" /> </target> First, using the exec task again, we create a symbolic link to a copy of Zend Framework that is required for this site to function. Second, using the delete task, we remove the symbolic link that points to the previous version of the site. Third, again using the exec task, we create a new symbolic link to the version of the site we just checked out of Subversion and prepared for deployment. As a nal step, we tell the Apache web server to reload its conguration to make sure that all changes will take effect right away. Since Apache doesn't run under my login, I need to use the sudo command, which will prompt me for the root / administrator password to perform this action. Putting it all together Now that we have constructed all the individual targets, we assemble all to create the nal build.xml le. For the complete listing, please refer to the build.xml le in the code bundle for this chapter. When I run this le for the development environment from the command line, I get the following output, which I broke up into two separate screenshots to accommodate the length of the listing. Download from Wow! eBook www.WoweBook.com Chapter 8 [ 359 ] Download from Wow! eBook www.WoweBook.com Deploying Applications [ 360 ] Not bad. Within slightly more than nine seconds, I was able to check out a project from Subversion, create some les from templates, put up a maintenance page, back up and upgrade the database, create various symbolic links and directories, and nally restart the web server. And that includes me having to type the administrator's password to be allowed to restart the server. Now let's take look at the site's changed directory structure. If you ip back a couple of pages, you can compare it to what it looked like before we restructured it to make upgrades easier. As a testament to the ease with which we can now deploy the site, I included in the listing the database upgrade/downgrade scripts (db-upgrade.xxxx.sql and db-upgrade.xxxx.sql); as well as, the top-level directories of the previously deployed applications that are now backed up (dev.waferthin.com.xxxx). Unfortunately, this means that the listing is so long that I had to split it into two separate screenshots. Download from Wow! eBook www.WoweBook.com Chapter 8 [ 361 ] The directory at the top of our hierarchy, dev.waferthin.com, now holds the following subdirectories: • backups: contains pre-upgrade database backups • build: contains incremental database upgrade and downgrade SQL scripts • dev.waferthin.com.YYYYMMDDHHMM: site source code with date stamp • dev.waferthin.com: symbolic link pointing to the current release • logs: logs les • tmp: temp directory for le manipulations Deploying the application to a test or production web server is equally simple. As long as you have Phing installed, all you have to do is copy the build.xml and environment properties les to the destination machine and run the corresponding target. Download from Wow! eBook www.WoweBook.com Deploying Applications [ 362 ] Backing out After the new site is live, we need to inspect it to make sure everything is running as intended. What if there are problems? If the issue isn't something we can x immediately, the plan is to back out of the upgrade and revert to the previous version. With the way our site is structured, this is merely a matter of changing the symbolic link to point to the old version of the application and to restart the web server. Optionally, depending on what upgrades were applied, you might also want to run the script to downgrade the database. That's it. Within a few seconds you can switch between two or more different versions of the site. Summary I hope that in reading this chapter you have gained a new perspective on how to deploy an application. Although deployment is often the last step in the development process, you need to start planning for it right from the start. Organizing your site's les in such a way that it lends itself to an automated deployment process is half the battle. We started out by discussing application deployment and trying to come up with some guidelines for measuring success. The process we developed managed to fulll both goals we had set ourselves. It is completely automated so as to minimize human errors and the time during which users of the application are negatively affected. Along the way of automating the deployment process, we learned about Phing and how it can be used to automate all kinds of tasks. Although we used it to deploy a site, Phing can really do a whole lot more. You can create targets to perform all kinds of maintenance on your code or site. For example, you have Phing synchronize les and directories or generate phpDocumentor documentation. There is no end to how much you can do with it. Download from Wow! eBook www.WoweBook.com [...]... exists If you look at UML diagramming tools, you will find that nearly all of them support Java Your selection narrows if you are looking for a tool that is capable of generating PHP 5+ compliant PHP code However, such tools are definitely available and we will be working with one later on in the chapter [ 366 ] Download from Wow! eBook www.WoweBook.com Chapter 9 If supported by the tool, it is also... Code Round - trip UML Code UML Code One - way Code to UML UML authoring tools that only generate code from diagrams are called one-way tools Similarly, tools that only generate UML diagrams from existing code are also called one-way tools In contrast, tools that work in both directions are often referred to as round-trip tools At this point, you don't need to be worried that your job of writing... PHP Application Design with UML After adding a couple of classes, our UML might look like this now: ServiceRunner +startPort:int[1] = null +endPort:int[1] = null 1 #connections:connection[*] = array 0. 655 35 Connection +port: int [1] = 80 +ip: string [1] = ‘127.0.0.1’ -socket: socket [0 1] = null -socketOpen: bool[1] = FALSE +_construct(host:string= ‘localhost’, StartPort: int = 0, endPort int = 655 35) ... the classes functional, but these tools can save you a lot of time—if you are creating UML diagrams anyway The quality of the code varies from one UML authoring tool to another While working on this chapter, I created some class diagrams in ArgoUML, one of the oldest and best-known UML diagramming tools I was pleasantly surprised that the PHP code it output was fully PHP5 object-oriented and quite usable... code package accompanying this chapter: • • • • • ServiceRunner .php interfaces/Interrogator .php classes/Probe .php classes/ProbeService .php classes/Connection .php Code generators I chose to write the above code from scratch However, as mentioned in the introduction to this chapter, there are tools that will take class diagrams and generate classes that contain all the components and relationships depicted... actual implementation of the above class: /ProbeService .php . diagramming tools, you will nd that nearly all of them support Java. Your selection narrows if you are looking for a tool that is capable of generating PHP 5+ compliant PHP code. However, such tools. authoring tools that only generate code from diagrams are called one-way tools. Similarly, tools that only generate UML diagrams from existing code are also called one-way tools. In contrast, tools. accommodate the length of the listing. Download from Wow! eBook www.WoweBook.com Chapter 8 [ 3 59 ] Download from Wow! eBook www.WoweBook.com Deploying Applications [ 360 ] Not bad. Within

Ngày đăng: 12/08/2014, 16:21

Từ khóa liên quan

Mục lục

  • Chapter 8: Deploying Applications

    • Automating deployment

      • Deploying a site

        • Maintenance page

        • Database backup

        • Database migrations

        • Going live

        • Putting it all together

        • Backing out

        • Summary

        • Meta-model versus notation versus our approach

        • Levels of detail and purpose

        • Round-trip and one-way tools

        • Basic types of UML diagrams

        • Diagrams

          • Class diagrams

            • Elements of a class

            • Static methods and properties

            • A class diagram example

            • Relationships

            • Interfaces

            • Example refactored

            • Code generators

            • Sequence diagrams

              • Scope

              • A sequence diagram of the network scanner

Tài liệu cùng người dùng

Tài liệu liên quan