1.
Set PHP’s session.auto_start ini setting in either php.ini or
.
htaccess
2.
Use Zend_Session
::
start()
3.
Use PHP's session_start() function directly
4.
Use new Zend_Session_Namespace() whenever needed, and the session will be
automatically started within Zend_Session
Zend_Session Best Practices:





ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
116
Slide 116

Copyright © 2006-2009, Zend Technologies Inc.
| 116
• Identity Persistence

Important to support maintaining the authenticated identity without having to
present the credentials with each request (due to stateless nature of HTTP)

Zend_Session used by default within Zend_Auth to provide persistence
• Lock

Session namespaces can be locked – using lock(), unlock(),
isLocked()- to prevent further alterations to the data in that namespace

Locks are transient, and do not persist across requests
Zend_Session Best Practices:



HTTP is a stateless protocol, however, and techniques such as cookies and sessions have been
developed in order to facilitate maintaining state across multiple requests in server-side web
applications. Zend_Session is used by default within Zend_Auth to provide persistent storage of
the identity from a successful authentication attempt using the PHP session


By default, Zend_Auth uses a storage class based on Zend_Session. The storage class may be
changed by providing a different storage object to Zend_Auth::setStorage()

Participant Guide | ZF Fundamentals
117
© 2006-2009 Zend Technologies, Inc.
Slide 117

Copyright © 2006-2009, Zend Technologies Inc.
| 117
Expiration:
• Limits can be placed on the longevity of both namespaces and individual keys in
namespaces – example:

for passing temporary information between requests

for reducing exposure to certain security risks by removing access to potentially
sensitive information ‘x’ time after authentication occurs)
• Expiration can be based on elapsed seconds, or based on the concept of "hops",
where a hop occurs for each successive request that activates the namespace
via
$space = new Zend_Session_Namespace('myspace');
• Can also use namespaces to separate session access by Controllers, to protect
variables from contamination – example:

'Authentication' controller might keep its session state data separate from all
other controllers
Zend_Session Best Practices:


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
118
Slide 118

Copyright © 2006-2009, Zend Technologies Inc.
| 118
Best Practice
Zend_Session, Locking, and the MVC Pattern Design:
There are numerous ideas on how to manage MVC designs for
the Web,including creating presentation layers for use by Views.
Sometimes existing data is adequate for the task,whether part of the
domain model or not.
Locking session namespaces before permitting access to this
subset of your"presentation"will prevent Views fromapplying any
processing logic to alter this existing data.
Zend_Session and MVC:



Another idea for the use of Locking – retaining your Design Pattern (MVC)


Useful for situations where may have different teams working on same applications (Views separate
team from Controllers)


Application is 'correcting' itself – will not let you do things it knows is wrong, such as modifying
Session data from the View by locking beforehand

Participant Guide | ZF Fundamentals
119
© 2006-2009 Zend Technologies, Inc.
Slide 119

Copyright © 2006-2009, Zend Technologies Inc.
|
119
Let’s look at how Zend_Session is used within the GB application
Zend_Session
Guest Book


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
120
Slide 120

Copyright © 2006-2009, Zend Technologies Inc.
|
120
Code the General Components:
1.Think about where these components
would appear in the application
2.Code the components with the
following requirements:
• Limit the number of failed post
requests to 3
• Throw an exception whenever the
failed number of post requests is
exceeded
3.Make sure to make a comment using
/* -- before each of your coding
pieces, so you can reference what you
have done later as you code the next
project
4.Test and Debug
Guest Book
Zend_Exception
Zend_Session


Participant Guide | ZF Fundamentals
121
© 2006-2009 Zend Technologies, Inc.
Slide 121

Copyright © 2006-2009, Zend Technologies Inc.Copyright © 2006-2009, Zend Technologies Inc.
MOD 6: Model Components of MVC
(Guest Book)


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
122
Slide 122

Copyright © 2006-2009, Zend Technologies Inc.
| 122
Model for the Guest Book Application
• First, we will look specifically at the ZF
components and functionality of the
Model layer


Participant Guide | ZF Fundamentals
123
© 2006-2009 Zend Technologies, Inc.
Slide 123

Copyright © 2006-2009, Zend Technologies Inc.
| 123
What is a Model?
• Models are more of an abstract concept within the MVC design pattern than
part of a pattern
• Modelling encompasses a variety of patterns:

Domain Models

Table Modules

Service Layers

Gateways

Value Objects, and more…
• Models encapsulate your business logic
• Your database is not a model; it simply stores data used by your models
• Data Access layers are part of your model



Models are more of an abstract concept than a part of the design pattern, as they are not actually
needed, but recommended


You can query directly from a Controller


There is no set definition as to how models work


The relationship between M <> V <> C is defined, but not how they actually work together


There are instances where using a model is not always appropriate


From a thought process, and an architectural standpoint, it makes sense to have a model for any
larger-sized application, when you want a function that just gets data


Controllers are not concerned with where or how data is stored


Database source changes are easier when you use a model, as you can make the change without
modifying the rest of the application, especially Controllers
ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
124
Slide 124

Copyright © 2006-2009, Zend Technologies Inc.
| 124
Models and Zend Framework
• Zend Framework itself does not provide a model (no Zend_Model)
 As stated, models are an abstract concept
 Models are too application-specific to provide a generic implementation that is useful
• Instead, ZF provides a number of tools to make models easier to write
 Very easy to use data access components:
Databases: Zend_Db
RSS: Zend_Feed
Services:Amazon, Flickr, and more...
Web Services: SOAP



ZF does not provide a ‘model’ because, as stated earlier, it is a concept

There is no generic model that will work in 100% of cases


Instead, ZF provides a number of tools that make creating a model much easier

DB, RSS Feed, Web Services

Participant Guide | ZF Fundamentals
125
© 2006-2009 Zend Technologies, Inc.
Slide 125

Copyright © 2006-2009, Zend Technologies Inc.
| 125
Models Best Practice
• Do not tie your model directly to data access… why?
• Testing is harder to conduct
• Refactoring to use caching or an SOA becomes harder
• Restructuring your database becomes problematic (code could break)


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
126
Slide 126

Copyright © 2006-2009, Zend Technologies Inc.
| 126
Models and Metadata / Attributes
• Models are Classes, so that is what you should create
 They usually have corresponding metadata
or attributes
 Remember to define them … Ex:


Participant Guide | ZF Fundamentals
127
© 2006-2009 Zend Technologies, Inc.
Slide 127

Copyright © 2006-2009, Zend Technologies Inc.
| 127
Models and Accessors / Mutators
 They usually have behavior
surrounding the metadata
 Remember to define their accessors and mutators … Ex:


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
128
Slide 128

Copyright © 2006-2009, Zend Technologies Inc.
| 128
Models Schema
 Also remember that you need to persist your model, defining a schema… Ex:


Participant Guide | ZF Fundamentals
129
© 2006-2009 Zend Technologies, Inc.
Slide 129

Copyright © 2006-2009, Zend Technologies Inc.
| 129
Models – Connect the Database
 Finally, remember that you need to connect your database to your application… Ex:
 We will now take a look at the most important ZF components related to the Model
layer, like Zend_Db, Zend_Db_Table, and others


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
130
Slide 130

Copyright © 2006-2009, Zend Technologies Inc.
| 130
Model Layer ZF Project Components
Zend_Db
Zend_Form


Participant Guide | ZF Fundamentals
131
© 2006-2009 Zend Technologies, Inc.
Slide 131

Copyright © 2006-2009, Zend Technologies Inc.Copyright © 2006-2009, Zend Technologies Inc.
Zend_Db


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
132
Slide 132

Copyright © 2006-2009, Zend Technologies Inc.
| 132
Zend_Db
• Zend_Db and its related classes provide a simple SQL database interface for ZF
• Zend_Db has a series of extension components that include:
_Adapter database API abstraction layer for ZF
_Profiler allows profiling of queries when enabled
_Select represents a SQL SELECT query statement, with methods
for adding individual parts to the query
_Table /_Table_Row /_Table_Rowset
Each of these extension components will be examined in more detail later…



Large collection of various components that have to do with accessing database data

Designed to be simple so that developers can easily link to DBs like SQL within their application,
without a great deal of knowledge of the DB, and yet still produce a robust application

Not designed like ORM (object relational mapping) in an active record pattern because of associated
performance hit (slowdown) due to constant introspection; not scalable, high-performance approach

Instead, developed tools like _Adapter, which combined accomplishes same goal but in a much
more pragmatic manner

Wrapper that unifies all the DB drivers for the underlying DBs under a consistent API

Step above a PDO

_Profiler is a built-in tool that is used for debugging purposes around performance – e.g., show
how many queries have completed; how long did each query take to run?

_Select is a builder class, allows you to construct very complex queries using an OO API

across different DB, eliminating specific DB-dependencies


_DB_Table is closest thing in ZF to ORM; defines table as an object, for which you can then define a
relationship
Participant Guide | ZF Fundamentals
133
© 2006-2009 Zend Technologies, Inc.
Slide 133

Copyright © 2006-2009, Zend Technologies Inc.
| 133
What does Zend_Db do?
• Database Abstraction Layer

vs. PDO, which is a database access layer
• Provides a variety of database adapters

PDO adapters

Driver specific adapters
• Abstraction of common functionality

limits/offsets

inserts/updates

Transactions
• Connects to database on-demand

Instantiating the object does not connect to the database - only when the first data
access occurs does it connect


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
134
Slide 134

Copyright © 2006-2009, Zend Technologies Inc.
| 134
How do I connect to a database?
• Basic Usage: Zend_Db::factory() with parameters


Participant Guide | ZF Fundamentals
135
© 2006-2009 Zend Technologies, Inc.
Slide 135

Copyright © 2006-2009, Zend Technologies Inc.
| 135
• Advanced Usage: Zend_Db::factory() with Zend_Config o bject

Zend_Config definition:

And now the connection:
How do I connect to a database?


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
136
Slide 136

Copyright © 2006-2009, Zend Technologies Inc.
| 136
Zend_Db_Adapter
• Zend_Db_Adapter is the basic class connect ing a PHP application to an
RDBMS
• There is a different Adapter class for each brand of RDBMS

Adapters create a bridge from vendor-specific PHP extensions to a common interface

Write PHP applications once and deploy with multiple brands of RDBMS with very
little effort
• Zend_Db provides Adapter classes to PDO drivers for the following RDBMS
brands: MySQL; Microsoft SQL Server; Oracle; PostgreSQL; SQLite
• Zend_Db also provides Adapter classes that utilize PHP database extensions
for the following RDBMS brands:

MySQL, using the mysqli PHP extension

Oracle, using the oci8 PHP extension

IBM DB2, using the ibm_db2 PHP extension


Participant Guide | ZF Fundamentals
137
© 2006-2009 Zend Technologies, Inc.
Slide 137

Copyright © 2006-2009, Zend Technologies Inc.
| 137
Zend_Db_Profiler
• Zend_Db_Profiler can be enabled to allow profiling of queries
• Profiles include the queries processed by the adapter as well as the elapsed
time to run the queries

This allows for inspection of queries performed without needing to add extra
debugging code to classes
• Advanced usage also allows the developer to filter which queries are profiled
• Enable the Profiler by either passing a directive to the Adapter constructor, or by
directing the Adapter to enable it later



Turn on application, run Profiler, exam the statistics, turn off

Can get very granular with filters


Enable when create the Adapter itself, or later

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
138
Slide 138

Copyright © 2006-2009, Zend Technologies Inc.
| 138
Using Zend_Db_Profiler:
• Enable Zend_Db_Profiler:


Participant Guide | ZF Fundamentals
139
© 2006-2009 Zend Technologies, Inc.
Slide 139

Copyright © 2006-2009, Zend Technologies Inc.
| 139
Using Zend_Db_Profiler:
• Use Zend_Db_Profiler:
 Call the Method
 Returns a Zend_Db_Profiler object instance
• Examine queries using the object instance via a variety of methods:
getTotalNumQueries() returns total number of queries profiled
getTotalElapsedSecs() returns total number of seconds elapsed for all
profiled queries
getQueryProfiles() returns array of all query profiles
getLastQueryProfile() returns last (most recent) query profile, regardless of
whether or not the query has finished (if it hasn't, the
end time will be null)
clear() clears any past query profiles from the stack



One of the most interesting is getTotalNumQueries()


Helps you to identify places where you may be losing performance due to multiple, perhaps
redundant, queries

places where you could use caching for better performance


Can also write a whole API (administrative interface) for this, that uses the other applications to show
the overall performance

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
140
Slide 140

Copyright © 2006-2009, Zend Technologies Inc.
| 140
Using Zend_Db_Profiler:
• getLastQueryProfile() returned values and getQueryProfiles()
elements are Zend_Db_Profiler_Query objects
• Objects provide ability to inspect individual queries themselves:
 getQuery() returns the SQL text of the query
 SQL text of a prepared statement with parameters is the text at the time the
query was prepared
 Contains parameter placeholders, not values used, when statement is
executed
 getQueryParams() returns an array of parameter values used when executing a
prepared query
 Includes both bound parameters and arguments to statement's execute()
method
 Array keys are positional (1-based) or named (string) parameter indices
 getElapsedSecs() returns the number of seconds the query ran



Zend_Db_Profiler_Query returns an array of profile query objects, which represent a particular
profile within a particular query


Many things you can do with these objects…

Can use getQuery()to receive back the actual SQL text

Very useful if you are going to use Db_Table because you don’t get to see the
actual SQL query you are constructing, so you have to use this to determine what is
actually going on

Participant Guide | ZF Fundamentals
141
© 2006-2009 Zend Technologies, Inc.
Slide 141

Copyright © 2006-2009, Zend Technologies Inc.
| 141
Using Zend_Db_Profiler:

Zend_Db_Profiler provides useful information for profiling bottlenecks in
applications, and debugging executed queries

Example - Query Run Last…



Zend_Db_Profiler_Query returns an array of profile query objects,

Example: If you need to know the last query that ran, you can use a method like
getLastQueryProfiler() that will return a profile query object for the last query, which
you can then echo out and analyze


So, with Zend_Db you can construct an infrastructure within the application itself that monitors
whether your queries are running optimally


Remember to keep this type of profiler query off unless in use, as you need to create an object in
memory for each query, which will lessen the available memory

For a normal application, would leave it ON during development, and then OFF in production

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
142
Slide 142

Copyright © 2006-2009, Zend Technologies Inc.
| 142
• The Zend_Db_Table class is an object-oriented interface to database tables
• It provides methods for many common operations on tables

The base class is extensible, so you can add custom logic
• The Zend_Db_Table solution is an implementation of the Table Data Gateway
pattern

The solution also includes a class that implements the Row Data Gateway
pattern
• You can instantiate Zend_Db_Table

Do not have to extend and configure a base class for simple operations
Zend_Db_Table


Participant Guide | ZF Fundamentals
143
© 2006-2009 Zend Technologies, Inc.
Slide 143

Copyright © 2006-2009, Zend Technologies Inc.
| 143
Defining a Class
• For each table in your database that you want to access, define a class that
extends Zend_Db_Table_Abstract

Declare the database table for which this class is defined, using the
protected variable $_name

The table name must be exactly as in the database
• You can also declare the schema for the table, either with the protected
variable $_schema, or with the schema prepended to the table name in the
$_name property

Any schema specified with the $_name property takes precedence over a
schema specified with the $_schema property
Zend_Db_Table


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
144
Slide 144

Copyright © 2006-2009, Zend Technologies Inc.
| 144
Defining the Table Primary Key
• Every table must have a primary key

You can declare the column for the primary key using the protected
variable $_primary

This is either a string that names the single column for the primary key, or
else it is an array of column names if your primary key is a compound key
• If you don't specify the primary key, Zend_Db_Table_Abstract tries to
discover the primary key based on the information provided by the
describeTable() method
Zend_Db_Table



Note: Every table class must know which column(s) can be used to address rows uniquely


If no primary key column(s) are specified in the table class definition or the table constructor
arguments, or discovered in the table metadata provided by describeTable(), then the table
cannot be used with Zend_Db_Table


Participant Guide | ZF Fundamentals
145
© 2006-2009 Zend Technologies, Inc.
Slide 145

Copyright © 2006-2009, Zend Technologies Inc.
| 145
Creating an Instance of a Table:
• Before you use a Table class, create an instance using its constructor
• There are three ways of specifying the database adapter to a Table class:
• Passing it as an object of type Zend_Db_Adapter_Abstract
• Setting a default database adapter
• Storing a database adapter in the Registry
Zend_Db_Table



The constructor's argument is an array of options, the most important being the database adapter
instance representing a live connection to an RDBMS


There are three ways to specify the database adapter:

Passing it as an object of type Zend_Db_Adapter_Abstract
The first way to provide a database adapter to a Table class is by passing it as an object of
type Zend_Db_Adapter_Abstract in the options array, identified by the key 'db'


Setting a default database adapter
The second way to provide a database adapter to a Table class is by declaring an object of
type Zend_Db_Adapter_Abstract to be a default database adapter for all subsequent
instances of Tables in your application. You can do this with the static method
Zend_Db_Table_Abstract::setDefaultAdapter(). The argument is an object of type
Zend_Db_Adapter_Abstract


Storing a database adapter in the Registry
The third way to provide a database adapter to a Table class is by passing a string in the options
array, also identified by the 'db' key. The string is used as a key to the static Zend_Registry
instance, where the entry at that key is an object of type Zend_Db_Adapter_Abstract

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
146
Slide 146

Copyright © 2006-2009, Zend Technologies Inc.
| 146
Inserting Rows:
• You can use the Table object to insert rows into the database table on which
the Table object is based by using the insert() method
• The argument is an associative array, mapping column names to values
• By default, the values in your data array are inserted as literal values, using
parameters
• If you need them to be treated as SQL expressions, you must make sure they
are distinct from plain strings - use an object of type Zend_Db_Expr
Zend_Db_Table



In the default behavior of Zend_Db_Table_Abstract, it is assumed that the table has an auto-
incrementing primary key, but, there are other types of primary keys as well

In Zend_Db_Table_Abstract, if you define the protected variable $_sequence to be the
Boolean value TRUE, then the class assumes that the table has an auto-incrementing primary
key


MySQL, Microsoft SQL Server, and SQLite are examples of RDBMS brands that support
auto-incrementing primary keys


PostgreSQL has a SERIAL notation that implicitly defines a sequence based on the table and
column name, and uses the sequence to generate key values for new rows


IBM DB2 has an IDENTITY notation that works similarly - if you use either of these notations,
treat your Zend_Db_Table class as having an auto-incrementing column with respect to
declaring the $_sequence member as TRUE

Participant Guide | ZF Fundamentals
147
© 2006-2009 Zend Technologies, Inc.
Slide 147

Copyright © 2006-2009, Zend Technologies Inc.
| 147
Updating Rows:
• You update rows in a database table using the update method of a Table class
• This method takes two arguments:

an associative array of columns to change and new values to assign to these
columns, and an

SQL expression that is used in a WHERE clause, as criteria for the rows to
change in the UPDATE operation
• Since the table update() method proxies to the DB adapter update()
method, the second argument can be an array of SQL expressions
Zend_Db_Table



Note :

The values and identifiers in the SQL expression are not quoted for you

If you have values or identifiers that require quoting, you are responsible for doing this. Use
the quote(), quoteInto(), and quoteIdentifier() methods of the database adapter.


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
148
Slide 148

Copyright © 2006-2009, Zend Technologies Inc.
| 148
Deleting Rows:
• You can delete rows from a database table using the delete() method
• This method takes one argument, which is an SQL expression that is used in a
WHERE clause, as criteria for the rows to delete
• Since the table delete() method proxies to the database adapter delete()
method, the argument can also be an array of SQL expressions
• You can also call the delete() method on a Row object, which we will see
in the Zend_Db_Table_Row section
Zend_Db_Table



The expressions are combined as Boolean terms using an AND operator.


Note: The values and identifiers in the SQL expression are not quoted for you.
If you have values or identifiers that require quoting, you are responsible for doing this.
Use the quote(), quoteInto(), and quoteIdentifier() methods of the database
adapter.



Participant Guide | ZF Fundamentals
149
© 2006-2009 Zend Technologies, Inc.
Slide 149

Copyright © 2006-2009, Zend Technologies Inc.
| 149
Querying Rows:
• You can query the database table for rows matching specific values in the
primary key, using the find() method

The first argument is either a single value or an array of values to match
against the primary key of the table

This method takes one argument, which is an SQL expression that is used in
a WHERE clause, as criteria for the rows to delete
• If you specify a single value, the method returns at most one row, because a
primary key cannot have duplicate values; specifying multiple values in an array,
returns at most as many rows as the number of distinct values you specify
Zend_Db_Table



Note:
The find() method might return fewer rows than the number of values you specify for the primary
key, if some of the values don't match any rows in the database table; the method even may return
zero rows.


Because the number of rows returned is variable, the find() method returns an object of type
Zend_Db_Table_Rowset_Abstract

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
150
Slide 150

Copyright © 2006-2009, Zend Technologies Inc.
| 150
Querying Rows: (continued)
• You can query for a set of rows with any criteria other than the primary key
values by using the fetchAll() method of the Table class
• This method returns an object of type Zend_Db_Table_Rowset_Abstract
• You may also pass sorting criteria in an ORDER BY clause, as well as count and
offset integer values, used to make the query return a specific subset of rows
• These values are used in a LIMIT clause, or in equivalent logic for RDBMS
brands that do not support the LIMIT syntax
Zend_Db_Table


Participant Guide | ZF Fundamentals
151
© 2006-2009 Zend Technologies, Inc.
Slide 151

Copyright © 2006-2009, Zend Technologies Inc.
| 151
• Zend_Db_Table_Row is a class that contains an individual row of a
Zend_Db_Table object
• When you run a query against a Table class, the result is returned in a set of
Zend_Db_Table_Row objects

Use this object to create new rows and add them to the database table
• Zend_Db_Table_Abstract provides methods find() and fetchAll(),
which each return an object of type Zend_Db_Table_Rowset, and the method
fetchRow(), which returns an object of type Zend_Db_Table_Row
• Zend_Db_Table_Row_Abstract provides accessor methods so you can
reference columns in the row as object properties.
• Zend_Db_Table_Row is the default concrete class that extends
Zend_Db_Table_Row_Abstract.
Zend_Db_Table_Row



Currently, Zend_Db_Table_Row does not implement inflection. Accessed property names need to
match the spelling of the column names as they appear in your database.


You can define your own concrete class for instances of Row by extending
Zend_Db_Table_Row_Abstract.


To use your new Row class to store results of Table queries, specify the custom Row class by name
either in the $_rowClass protected member of a Table class, or in the array argument of the
constructor of a Table object

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
152
Slide 152

Copyright © 2006-2009, Zend Technologies Inc.
| 152
• You can access the row's data as an array using the toArray() method of the
Row object

This returns an associative array of the column names to the column values
• The Zend_Db_Table_Row_Abstract class provides methods for fetching rows
and rowsets from related tables
Zend_Db_Table_Row


Participant Guide | ZF Fundamentals
153
© 2006-2009 Zend Technologies, Inc.
Slide 153

Copyright © 2006-2009, Zend Technologies Inc.
| 153
Writing Rows to the Database
• You can set individual column values using column accessors, similar to how the
columns are read as object properties in the example on the previous slide
• Using a column accessor to set a value changes the column value of the row
object in your application, but it does not commit the change to the database yet
– you can do that with the save() method
• You can create a new row for a given table with the createRow() method of the
table class
• You can access fields of this row with the object-oriented interface, but the row is
not stored in the database until you call the save() method

Zend_Db_Table_Row


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
154
Slide 154

Copyright © 2006-2009, Zend Technologies Inc.
| 154
Deleting a Row
• You can call the delete() method on a Row object
• This deletes rows in the database matching the primary key in the Row object
• You do not have to call save() to apply the delete; it is executed against the
database immediately
Zend_Db_Table_Row


Participant Guide | ZF Fundamentals
155
© 2006-2009 Zend Technologies, Inc.
Slide 155

Copyright © 2006-2009, Zend Technologies Inc.
| 155
• When you query against a Table class using find() or fetchAll(), the result
is returned in an object of type Zend_Db_Table_Rowset_Abstract.
• A Rowset contains a collection of objects descending from
Zend_Db_Table_Row_Abstract
• You can iterate through the Rowset and access individual Row objects, reading or
modifying data in the Rows
• You can access all the data in the Rowset as an array using the toArray()
method of the Rowset object
• You can use an alternative concrete class for instances of Rowsets by extending
Zend_Db_Table_Row_Abstract
• Specify the custom Rowset class by name either in the $_rowsetClass
protected member of a Table class, or in the array argument of a Table Object
constructor
Zend_Db_Table_Rowset


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
156
Slide 156

Copyright © 2006-2009, Zend Technologies Inc.
| 156
• Tables have relationships to each other in a relational database
• An entity in one table can be linked to one or more entities in another table by
using referential integrity constraints defined in the database schema
• The Zend_Db_Table_Row class has methods for querying related rows in other
tables
• Define classes for each of your tables by extending the abstract class
Zend_Db_Table_Abstract (as seen earlier)
• Fetch Dependent Rowset: If you have a Row object as the result of a query on a
parent table, you can fetch rows from dependent tables that reference the current
row. Use the method: $row->findDependentRowset($table,[$rule]);
• Fetch Parent Row:If you have a Row object as the result of a query on a
dependent table, you can fetch the row in the parent to which the dependent row
refers. Use the method: $row->findParentRow($table,[$rule]);
Zend_Db_Table Relationships


Participant Guide | ZF Fundamentals
157
© 2006-2009 Zend Technologies, Inc.
Slide 157

Copyright © 2006-2009, Zend Technologies Inc.
| 157
• Zend_Db_Table_Definition is a class
that can be used to describe the
relationships and configuration options
that should be used when
Zend_Db_Table is used via concrete
instantiation
• All of the same options that are available
when configuring an extended
Zend_Db_Table_Abstract class are
also available when describing a definition
file
• The definition file should be passed to the
class at the time of instantiation to convey
the full definition of all the tables
Zend_Db_Table_Definition


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
158
Slide 158

Copyright © 2006-2009, Zend Technologies Inc.
|
158
Using Zend_Db_Table:
Fill in the missing code for this section that creates a default database adapter:


Participant Guide | ZF Fundamentals
159
© 2006-2009 Zend Technologies, Inc.
Slide 159

Copyright © 2006-2009, Zend Technologies Inc.
| 159
• Query Abstraction
• Object Oriented, fluent interface for dynamically building queries:
Zend_Db_Select


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
160
Slide 160

Copyright © 2006-2009, Zend Technologies Inc.
| 160
• Represents a SQL SELECT query statement that has methods for adding
individual parts to the query

Specify parts of the query using PHP methods and data structures

Class forms the correct SQL syntax for you

After a query is built, execute the query as if it were a string
• The value offered by Zend_Db_Select includes:

OO methods for specifying SQL queries in piece-by-piece manner

DB independent abstraction of some parts of the SQL query

Automatic quoting of metadata identifiers in most cases, to support
identifiers containing SQL reserved words and special characters

Quoting identifiers and values reduce risk of SQL injection attacks
 For very simple SELECT queries, it is usually simpler to specify the entire SQL
query as a string and execute it using Adapter methods like query() or
fetchAll()
Zend_Db_Select


Participant Guide | ZF Fundamentals
161
© 2006-2009 Zend Technologies, Inc.
Slide 161

Copyright © 2006-2009, Zend Technologies Inc.
| 161
Zend_Db_Select
• Support for:

Joins

ORDER

HAVING

GROUP
• All select objects are specific to the current adapter

Abstracts the final query according to the needs of the underlying
database


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
162
Slide 162

Copyright © 2006-2009, Zend Technologies Inc.
| 162
• Create an instance of a Zend_Db_Select object using the select() method
of a Zend_Db_Adapter_Abstract object
Zend_Db_Select Objects
• Alternatively, create a Zend_Db_Select object with its constructor,
specifying the database adapter as an argument


Participant Guide | ZF Fundamentals
163
© 2006-2009 Zend Technologies, Inc.
Slide 163

Copyright © 2006-2009, Zend Technologies Inc.
| 163
Using Methods to Add Clauses
:
Example: Building Select Queries
Using the Fluent Interface:


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
164
Slide 164

Copyright © 2006-2009, Zend Technologies Inc.
| 164
Using the from() Method:
Example: Building Select Queries


Participant Guide | ZF Fundamentals
165
© 2006-2009 Zend Technologies, Inc.
Slide 165

Copyright © 2006-2009, Zend Technologies Inc.
|
165
Using the join() Method:
You have just seen how to build a query using the from() method - now use that
knowledge and apply it to this exercise where you utilize both the from() and
join() methods…
Exercise: Building Select Queries


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
166
Slide 166

Copyright © 2006-2009, Zend Technologies Inc.
| 166
How do I debug Zend_Db?
Debug using Zend_Db_Profiler
 Stores what queries have been run on the current adapter
 Stores the parameters used for prepared statements
 Has timing information for each query run


Participant Guide | ZF Fundamentals
167
© 2006-2009 Zend Technologies, Inc.
Slide 167

Copyright © 2006-2009, Zend Technologies Inc.
|
167
Let’s look at how Zend_Db is used within the GB application
Zend_Db
Guest Book


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
168
Slide 168

Copyright © 2006-2009, Zend Technologies Inc.
|
168
Code the Model Components:
1.Think about where this component
would appear in the application
2.Add a model class from the
database Table and a model class
from the database Row
3.Make sure to add comments before
each code section you add using
the /* -- format, so you can
reference your additions during the
next project
4.Test and Debug
Guest Book
Zend_Db


Participant Guide | ZF Fundamentals
169
© 2006-2009 Zend Technologies, Inc.
Slide 169

Zend_Form




ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
170
Slide 170

Copyright © 2006-2009, Zend Technologies Inc.
| 170
Zend_Form
• Zend_Form simplifies form creation and handling in your web application
• It accomplishes the following goals:

Element input filtering and validation

Element ordering

Element and Form rendering, including escaping

Element and form grouping

Element and form-level configuration
• It heavily leverages other ZF components to accomplish these goals, including:
Zend_Config Zend_Validate Zend_Loader_PluginLoader
Zend_Filter Zend_View (optional)



Zend_Form acts as a general purpose normalization and validation filter


Form decorators make it trivial to create the markup needed to capture data

We will look at decorators shortly


Zend_Form encapsulates i1 8n/l1 0n concerns for validation error reporting


There are many aspects to studying Zend_Form, some of which are advanced topics


The treatment of Zend_Form in this course is at the basic level… the Advanced Zend Framework
course will cover the more advanced aspects of this component

Participant Guide | ZF Fundamentals
171
© 2006-2009 Zend Technologies, Inc.
Slide 171

Copyright © 2006-2009, Zend Technologies Inc.
| 171
Zend_Form: Features and Benefits
• Internationalization: localize forms for customers
• Partial and Full Set data validation
• Filter and Validation chains per element
• Fully customizable output
• Adheres to Zend_Validate_Interface

Allows you to plug forms and/or elements in as validators for your models

Could potentially replace Zend_Filter_Input classes in your models
and thus make your models directly renderable
• Break forms into visual and/or logical groups


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
172
Slide 172

Copyright © 2006-2009, Zend Technologies Inc.
| 172
Zend_Form: Basic Usage
• Before we look into the architecture and other technical aspects of forms,
we are going to walk through the simple steps of creating a form:
1.
Create elements: Username
2.
Create elements: Password
3.
Create elements: Login Button
4.
Create elements: Form Object
5.
Create elements: View Script


Participant Guide | ZF Fundamentals
173
© 2006-2009 Zend Technologies, Inc.
Slide 173

Copyright © 2006-2009, Zend Technologies Inc.
| 173
Zend_Form : Basic Usage
Create elements: Username
• Multiple filters (filter chain!)
• Multiple validators (validator chain!)
• Required
• Don't forget the label!


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
174
Slide 174

Copyright © 2006-2009, Zend Technologies Inc.
| 174
Zend_Form : Basic Usage
Create elements: Password
• Single filter
• Single validator
• Required
• Don't forget the label!


Participant Guide | ZF Fundamentals
175
© 2006-2009 Zend Technologies, Inc.
Slide 175

Copyright © 2006-2009, Zend Technologies Inc.
| 175
Zend_Form : Basic Usage
Create elements: Login button
• Need to display the button
• But… we don't want to validate it or include it when pulling values


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
176
Slide 176

Copyright © 2006-2009, Zend Technologies Inc.
| 176
Zend_Form : Basic Usage
Create the Form object:
• Attach elements
• Check if valid - does all input filtering
• Pass it to the View


Participant Guide | ZF Fundamentals
177
© 2006-2009 Zend Technologies, Inc.
Slide 177

Copyright © 2006-2009, Zend Technologies Inc.
| 177
Zend_Form : Basic Usage
Create the view script:


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
178
Slide 178

Copyright © 2006-2009, Zend Technologies Inc.
| 178
Zend_Form : Basic Usage
First time viewing the form:


Participant Guide | ZF Fundamentals
179
© 2006-2009 Zend Technologies, Inc.
Slide 179

Copyright © 2006-2009, Zend Technologies Inc.
| 179
Zend_Form : Basic Usage
Results when submitting empty values:
NOTE: The Required flag has a correlation with the errors reported


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
180
Slide 180

Copyright © 2006-2009, Zend Technologies Inc.
| 180
Zend_Form : Basic Usage
Results when submitting invalid values:
NOTE: Errors are reported!


Participant Guide | ZF Fundamentals
181
© 2006-2009 Zend Technologies, Inc.
Slide 181

Copyright © 2006-2009, Zend Technologies Inc.
| 181
Zend_Form : Architecture Overview
• Base classes

forms

elements

display groups

sub forms
• Plugins

filters

validators

decorators

elements
• Utilities
 plugin loaders
 translators



Now, the nuts and bolts

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
182
Slide 182

Copyright © 2006-2009, Zend Technologies Inc.
| 182
Classes : Zend_Form
• Model Forms

Store and manipulate collections of elements and groups of elements

Validate attached elements and sub forms

Store and manipulate decorators for rending the form
• Class
:
Zend_Form


Participant Guide | ZF Fundamentals
183
© 2006-2009 Zend Technologies, Inc.
Slide 183

Copyright © 2006-2009, Zend Technologies Inc.
| 183
Classes: Zend_Form_Element
• Store and manipulate element
metadata
• Store and manipulate validator
chains
• Store and manipulate filter chains
• Store and manipulate decorators
for rendering element
• Base class:
Zend_Form_Element
Element types:
Button
Checkbox
Hash (CSRF protection)
Hidden
Image
MultiCheckbox
Multiselect
Password
Radio
Select
Submit
Text
Textarea
… and more


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
184
Slide 184

Copyright © 2006-2009, Zend Technologies Inc.
| 184
Classes: Zend_Form_DisplayGroup
• Group elements visually when rendering
• Collection of one or more elements
• Order display group in form, and elements within display group
• Class:Zend_Form_DisplayGroup


Participant Guide | ZF Fundamentals
185
© 2006-2009 Zend Technologies, Inc.
Slide 185

Copyright © 2006-2009, Zend Technologies Inc.
| 185
Classes: Zend_Form_SubForm
• Group elements logically

For display purposes

For validation purposes
• Potential uses

Multi-page forms (each sub form used per page)

Dynamic forms (for example, a "todo" list, where each "todo" item is
its own mini-form)
• Class: Zend_Form_SubForm


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
186
Slide 186

Copyright © 2006-2009, Zend Technologies Inc.
|
186
Let’s take a look at how Zend_Form functions in the GB Application
Zend_Form
Guest Book


Participant Guide | ZF Fundamentals
187
© 2006-2009 Zend Technologies, Inc.
Slide 187



ZF Fundamentals | Instructor Guide
© 2006-2009 Zend Technologies, Inc.
188
Slide 188

MOD 7: View Components of MVC
(Guest Book)


Participant Guide | ZF Fundamentals
189
© 2006-2009 Zend Technologies, Inc.
Slide 189

Copyright © 2006-2009, Zend Technologies Inc.
| 189
Code Structure for the Guest Book Application
• First, we will look specifically at the ZF
components and functionality of the
View layer


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
190
Slide 190

Copyright © 2006-2009, Zend Technologies Inc.
| 190
View ZF Project Components
Guest Book
Zend_View
Zend_Layout


Participant Guide | ZF Fundamentals
191
© 2006-2009 Zend Technologies, Inc.
Slide 191

Copyright © 2006-2009, Zend Technologies Inc.
| 191
How does ZF do Views?
• Zend_View renders view scripts written in PHP

PHP is itself a templating language; let's leverage it

Why force developers to learn another domain-specific language?
• ZF recommends using short tags and alternate logical/looping syntax for
brevity and readability of view scripts

But you can use long tags if you want
• Provides basic functionality for assigning variables and conditionally
escaping data



The use of Short tags with View Scripts is an exception to the rule - in all other instances, the ZF
conventions do not permit their use

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
192
Slide 192

Copyright © 2006-2009, Zend Technologies Inc.
| 192
Example View Script


Participant Guide | ZF Fundamentals
193
© 2006-2009 Zend Technologies, Inc.
Slide 193

Copyright © 2006-2009, Zend Technologies Inc.
| 193
Benefits to Using a View
• There are some real reasons for using views:

Efficiency: To keep presentation logic out of controllers and models

Variable namespaces: most views will allow you to scope your variables on
the presentation level

Security: Views allow you to better identify and prevent potential security
vulnerabilities in your application

Logistics: Often those who design the look and feel of an application don’t
design the backend development logic


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
194
Slide 194

Zend_View


Participant Guide | ZF Fundamentals
195
© 2006-2009 Zend Technologies, Inc.
Slide 195

Copyright © 2006-2009, Zend Technologies Inc.
| 195
Zend_View
• Zend_View is a class for working with the “View” portion of the MVC design
pattern
• It provides a system of helpers, output filters, & variable escaping
• Zend_View is not tied to one template system - it can utilize PHP templates or
other systems, manipulated through the view script
• Two major steps:

Controller script creates an instance of Zend_View and assigns variables to
that instance

Controller instructs Zend_View to render a particular view, which passes
control over to the view script that then generates the view output


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
196
Slide 196

Copyright © 2006-2009, Zend Technologies Inc.
| 196
Zend_View Script Configuration Options
• Zend_View has a series of options to configure the behavior of its scripts:

basePath:
• Assumes the directory structure depicted in diagram
• Path from which to set script, helper, and filter path
• May be set via setBasePath(), addBasePath(),or the basePath option to
the constructor

encoding
:
• Indicates the character encoding to use with htmlentities(),
htmlspecialchars() and other operations
• Defaults to ISO-8859-1 (latin1)
• May be set via setEncoding() or the escape option to the constructor
Base/path
helpers
filters
scripts/



Note that all these script configuration options can be set by using constructor options

Participant Guide | ZF Fundamentals
197
© 2006-2009 Zend Technologies, Inc.
Slide 197

Copyright © 2006-2009, Zend Technologies Inc.
| 197
Zend_View Script Configuration Options

escape
:
• Used to indicate a callback
• May be set via setEscape() or the escape option to the constructor

filter:
• Indicates filter to be used after rendering view script
• May be set via setFilter(), addFilter(), or the filter option to the
constructor

strictVars:
• Forces Zend_View to emit notices and warnings when uninitialized view
variables are access
• May be set by calling strictVars(true) or by passing the strictVars
option to the constructor


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
198
Slide 198

Copyright © 2006-2009, Zend Technologies Inc.
| 198
In this example, the controller has a list of book data to be rendered in a view:
Example: Zend_View Controller Script


Participant Guide | ZF Fundamentals
199
© 2006-2009 Zend Technologies, Inc.
Slide 199

Copyright © 2006-2009, Zend Technologies Inc.
| 199
Continuing the previous example, this is the associated view script for the
Zend_View controller script:
Example: Zend_View View Script



Now, here is the associated View Script for the previous example…


What makes it different from other standard PHP scripts is that it executes inside the scope of the
Zend_View instance, which means that references to $this point to the Zend_View instance
properties and methods


Note how we use the "escape()" method to apply output escaping to variables

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
200
Slide 200

Copyright © 2006-2009, Zend Technologies Inc.
| 200
Compare the following two programs - can you detect the advantage in the second approach?
Exercise: Zend_View Controller Scripts



(First example): Your controller script should assign necessary variables to the view before it hands
over control to the view script. Normally, you can do assignments one at a time by assigning to
property names of the view instance, but this can be tedious when you have already collected the
values to be assigned into an array or object.


(Second example): The assign() method lets you assign from an array or object "in bulk." The
following examples have the same effect as the above one-by-one property assignments.


Participant Guide | ZF Fundamentals
201
© 2006-2009 Zend Technologies, Inc.
Slide 201

Copyright © 2006-2009, Zend Technologies Inc.
| 201
The controller tells Zend_View to render a particular script by calling the render()
method
Rendering A View Script
By default, Zend_View expects your view scripts to be relative to your calling script.
Ex:
if your controller script is at/path/to/app/controllers
and it calls $view->render('someView.php‘)
Zend_View will look for/path/to/app/controllers/someView.php
To direct Zend_View where to look, use the setScriptPath() method



CONTINUING ON WITH THE PREVIOUS EXAMPLE…


Once you have assigned all needed variables, the controller should tell Zend_View to render a
particular view script.


Call the render() method.

Note that the method will return the rendered view, not print it, so you need to print or echo it
yourself at the appropriate time.

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
202
Slide 202

Copyright © 2006-2009, Zend Technologies Inc.
| 202

Recall that Zend_View executes a requested view script ‘inside’ the scope of the
Zend_View instance

Consequently, references to $this actually point to the Zend_View instance
itself

Variables assigned to the view from the controller are referred to as ‘instance
properties’

Example: variable "vacation"is referred to
as "$this->vacation"

Critical that output is escaped properly in the view script

Zend_View contains the method escape() to do this for you

Default: escape() uses PHP’s htmlspecialchars() function

Can use the setEscape() method at controller level to override default
View Scripts
Why is this so
important?


Participant Guide | ZF Fundamentals
203
© 2006-2009 Zend Technologies, Inc.
Slide 203

Copyright © 2006-2009, Zend Technologies Inc.
| 203
Zend_Viewprovides two mechanisms for using alternative (non-PHP) templates:
1.Via View Scripts
2. By implementing Zend_View_Interface
Via View Scripts (using a PHPLIB-style template) Related Template Files
Zend_View and Template Systems


Looking at the first mechanism:


a view script may be used to instantiate and manipulate a separate template object, such as a
PHPLIB-style template

The view script for that kind of activity might look something like above, with its related
template files…

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
204
Slide 204

Copyright © 2006-2009, Zend Technologies Inc.
| 204
Zend_View and Template Systems
ImplementingZend_View_Interface


Looking at the second mechanism:


You may find it easier to simply provide a Zend_View compatible template engine


Zend_View_Interface defines the minimum interface needed for compatibility


Zend Framework manual presents a third-party template engine - “Smarty” - in section 35.3.2.2.

Too lengthy to display here

Go to manual section if want to display code…


Participant Guide | ZF Fundamentals
205
© 2006-2009 Zend Technologies, Inc.
Slide 205

Zend_Layout


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
206
Slide 206

Copyright © 2006-2009, Zend Technologies Inc.
| 206
What Are “Layouts”?
• Zend_Layout is Zend Framework's solution for Two-Step View and
Composite View design patterns

Wrap application content in a sitewide template, the layout

Allow hinting from application views to sitewide layout

Layout scripts are just view scripts
• All the functionality of Zend_View is available

By default, any response segment is available as a layout
placeholder - the default, 'content', is always available
• Layout scripts are simply view scripts
• The internal implementation utilizes front controller plugins, action
helpers, and view helpers


The main goals of Zend_Layout are:

Automate selection and rendering of layouts when used with the Zend Framework MVC
components

Provide separate scope for layout related variables and content

Allow configuration, including layout name, layout script resolution (inflection), and layout
script path

Allow disabling layouts, changing layout scripts, and other states; allow these actions from
within action controllers and view scripts

Follow same script resolution rules (inflection) as the ViewRenderer, but also allow using
different rules

Allow usage without Zend Framework MVC components

Participant Guide | ZF Fundamentals
207
© 2006-2009 Zend Technologies, Inc.
Slide 207

Copyright © 2006-2009, Zend Technologies Inc.
| 207
Zend_Layout Usage: Basic Example
• Early in your application:

Specify doctype

Initialize layout with layout path


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
208
Slide 208

Copyright © 2006-2009, Zend Technologies Inc.
| 208
Zend_Layout Usage: Basic Example
• In your layout view script, render placeholders and sitewide elements:
• In your view script, hint to the layout:


Participant Guide | ZF Fundamentals
209
© 2006-2009 Zend Technologies, Inc.
Slide 209

Copyright © 2006-2009, Zend Technologies Inc.
| 209
Zend_Layout WITH MVC
• Zend_Controller offers a rich set of functionality for extension via its
front controller plugins and action controller helpers
• Zend_View also has helpers
• Zend_Layout takes advantage of these various extension points when
used with the MVC components.

Zend_Layout::startMvc() creates an instance of Zend_Layout
with any optional configuration you provide it

It then registers a front controller plugin that renders the layout with
any application content once the dispatch loop is done

It registers an action helper to allow access to the layout object from
your action controllers

Additionally, you can grab the layout instance at any time from within
a view script using the layout view helper



As noted in the previous slide, Zend_Layout can be utilized without MVC…

first, we will take a look at the advantages of using both together

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
210
Slide 210

Copyright © 2006-2009, Zend Technologies Inc.
| 210
Zend_Layout WITH MVC
Initialization:
• startMvc() can take an array of options or a Zend_Config object to
customize the instance


Participant Guide | ZF Fundamentals
211
© 2006-2009 Zend Technologies, Inc.
Slide 211

Copyright © 2006-2009, Zend Technologies Inc.
| 211
Zend_Layout WITH MVC: Action Controller
• In an action controller, you may then access the layout instance as an
action helper


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
212
Slide 212

Copyright © 2006-2009, Zend Technologies Inc.
| 212
Zend_Layout WITH MVC: View Scripts
• In your view scripts, you can access the layout object via the layout view
helper
• This view helper is slightly different than others in that it takes no
arguments, and returns an object instead of a string value

This allows you to immediately call methods on the layout object
• At any time, you can fetch the Zend_Layout instance registered with the
MVC via the getMvcInstance() static method


Recommendations for Use:

View Scripts should be concise

Hint to the layout script from your view scripts (not your controllers)

Layouts should use placeholders as much as possible

Set up common layout elements in a bootstrap resource



Participant Guide | ZF Fundamentals
213
© 2006-2009 Zend Technologies, Inc.
Slide 213

Copyright © 2006-2009, Zend Technologies Inc.
| 213
Zend_Layout WITHOUT MVC
• As a standalone component, Zend_Layout does not offer nearly as many
features or as much convenience as when used with MVC
• However, it still has two chief benefits:
 Scoping of layout variables
 Isolation of layout view script from other view scripts
• When used as a standalone component:
1.Simply instantiate the layout object
2.Use the various accessors to set state, set variables as object properties,
and render
the layout


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
214
Slide 214

Copyright © 2006-2009, Zend Technologies Inc.
| 214
Zend_Layout WITHOUT MVC


Participant Guide | ZF Fundamentals
215
© 2006-2009 Zend Technologies, Inc.
Slide 215

Copyright © 2006-2009, Zend Technologies Inc.
|
215
Let’s take a look at how Zend_Layout is functioning within the GB Application
Zend_Layout
Guest Book


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
216
Slide 216

Copyright © 2006-2009, Zend Technologies Inc.
|
216
Code the View Components:
1.Think about where these
components would appear
in the application
2.Implement views for each of
the corresponding controller
actions
3.Make sure to make a
comment using /* -- before
each of your coding pieces,
so you can reference what
you have done later as you
code the next project
4.Test and Debug
Guest Book
Zend_View
Zend_Layout


Participant Guide | ZF Fundamentals
217
© 2006-2009 Zend Technologies, Inc.
Slide 217

Introduction to the Wiki Application


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
218
Slide 218

Copyright © 2006-2009, Zend Technologies Inc.
| 218
Demonstration of the Wiki Application

First, let's look at the Wiki application and
how it functions...




Participant Guide | ZF Fundamentals
219
© 2006-2009 Zend Technologies, Inc.
Slide 219

Copyright © 2006-2009, Zend Technologies Inc.
| 219
Now that you’ve seen the Wiki
in action, and given the
architecture depicted, can you
guess what function these
elements have within the
application?
• MenuLeft.php
• _editListing.phtml
Wiki Application: MVC Architecture


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
220
Slide 220

MOD 8: Controller Components of MVC
(Wiki)


Participant Guide | ZF Fundamentals
221
© 2006-2009 Zend Technologies, Inc.
Slide 221

Copyright © 2006-2009, Zend Technologies Inc.
| 221
Controller Components
• We have already learned about the following components, and examined them
within the Guest Book application
• Now, we will see how they function within a more complex application, the Wiki
application:
Zend_Controller
Zend_Controller_Front
• The Wiki application introduces new components related to the Controller layer:
Front Controller Plugins
Action Helpers


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
222
Slide 222

Copyright © 2006-2009, Zend Technologies Inc.
| 222
Controllers for the Wiki Application
• First, we will look specifically at the ZF
components and functionality of the
Controller components we examined
previously in the practice applications
• Then, we will examine the new
components utilized in the wiki


Participant Guide | ZF Fundamentals
223
© 2006-2009 Zend Technologies, Inc.
Slide 223

Front Controller Plugins


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
224
Slide 224

Copyright © 2006-2009, Zend Technologies Inc.
| 224
Front Controller Plugins Overview
• Plugins hook into the events triggered by the Front Controller

Routing

Dispatch Loop

Dispatching Actions
• Plugin Hooks bookend each event

routeStartup()/routeShutdown()

dispatchLoopStartup()/dispatchLoopShutdown()

preDispatch()/postDispatch()
• Register plugins to affect the entire MVC application

Setting up ACLs

Setting up common view configuration and/or layouts

Branching based on the request or response



We have already looked at the Front Controller concept, both in studying the "Hello, World" application and
the Guest Book application


Now, we introduce the concept of the Plugin

Participant Guide | ZF Fundamentals
225
© 2006-2009 Zend Technologies, Inc.
Slide 225

Copyright © 2006-2009, Zend Technologies Inc.
| 225
Using Front Controller Plugins
• Register plugin instances with the Front Controller


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
226
Slide 226

Copyright © 2006-2009, Zend Technologies Inc.
| 226
Writing Front Controller Plugins
• Extend Zend_Controller_Plugin_Abstract, and implement one or more
hook methods:


Participant Guide | ZF Fundamentals
227
© 2006-2009 Zend Technologies, Inc.
Slide 227

Action Helpers


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
228
Slide 228

Copyright © 2006-2009, Zend Technologies Inc.
| 228
Action Helpers Overview
• Action Helpers extend the capabilities of Controllers

Introspection into the current Controller

Ability to interact with any public method of the Controller

Negates the need to create “base” controllers with common functionality
• Action Helpers may be used on-demand

No overhead unless you use them

Register helper class prefixes to provide a lookup table, while overriding existing helpers
 Action helpers may be used to automate tasks requiring introspection of the
Controller

Hooks into init(), preDispatch() and postDispatch()

Example: ViewRenderer injects view property into Controller during init(),and
renders a view based on the current controller and action (as determined from the
request object) during postDispatch()



Another new concept, that of the Action Helper


Action Helpers:

Eliminate the need to create custom base controller classes

Re-usable functionality that requires integration with or access from action controllers

Have pre-/postDispatch hooks, allowing for task automation


Participant Guide | ZF Fundamentals
229
© 2006-2009 Zend Technologies, Inc.
Slide 229

Copyright © 2006-2009, Zend Technologies Inc.
| 229
Using Action Helpers
• Access to helpers is through the Action Helper Broker, registered as the
$_helper property of the Controller
• Retrieve the helper using getHelper(), or rely on overloading, and access
by name
• Use just the last segment of the class following the common class prefix:


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
230
Slide 230

Copyright © 2006-2009, Zend Technologies Inc.
| 230
Using Action Helpers
• Calling helpers as method calls proxies to their direct() method, which usually
covers the most common use case for the helper:


Participant Guide | ZF Fundamentals
231
© 2006-2009 Zend Technologies, Inc.
Slide 231

Copyright © 2006-2009, Zend Technologies Inc.
| 231
• Action Helpers extend Zend_Controller_Action_Helper_Abstract
• Create a direct() method if you want to use the helper as if it were a
method
• Access the action controller using getActionController()
• Otherwise, simply create the functionality you need
Writing Action Helpers


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
232
Slide 232

Copyright © 2006-2009, Zend Technologies Inc.
| 232
Registering Action Helpers with the Broker
• Three strategies for registering Action Helpers with the Helper Broker:

Register a concrete instance

Register a class prefix (maps 1:1 to the file system) to helpers

Register a class prefix and path to helpers
• All registration is done statically
• Usually register from your bootstrap or a front controller plugin


Participant Guide | ZF Fundamentals
233
© 2006-2009 Zend Technologies, Inc.
Slide 233

MOD 9: General Components of MVC
(Wiki)


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
234
Slide 234

Copyright © 2006-2009, Zend Technologies Inc.
| 234
General Components in the Wiki Application
• We have already learned about the following components, and examined them
within the Guest Book application
• Now, we will see how they function within a more complex application, the Wiki
application:
Zend_Config
Zend_Exception
Zend_Session
• The Wiki application introduces two new general components
Zend_Registry
Zend_Log


Participant Guide | ZF Fundamentals
235
© 2006-2009 Zend Technologies, Inc.
Slide 235

Copyright © 2006-2009, Zend Technologies Inc.
| 235
General Components in the Wiki Application
• First, we will look specifically at the ZF general components we have
already utilized in the practice applications
• Then, we will look at the new components the wiki application utilizes


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
236
Slide 236

Zend_Registry


Participant Guide | ZF Fundamentals
237
© 2006-2009 Zend Technologies, Inc.
Slide 237

Copyright © 2006-2009, Zend Technologies Inc.
| 237
Zend_Registry
• Static storage of objects and arbitrary key/value pairs for global access

Makes them accessible continuously throughout the program

This mechanism is an alternative to using the global namespace
• Typical usage is through static methods in the Zend_Registry class

As the class is an array object, can also access stored elements with a
convenient array-like interface
• Used by some components internally

Always uses class name as key

Zend_Translate

Zend_Auth



The registry is a container for storing objects and values in the application space


By storing an object or value in the registry, the same object or value is always available throughout your
application for the lifetime of the request


This mechanism is often an acceptable alternative to using global variables.

provides globally accessible storage for objects and values

provides an iterator, array, and indexed access

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
238
Slide 238

Copyright © 2006-2009, Zend Technologies Inc.
| 238

To store an entry in the registry, use the static method, set()

The value can be an object, an array, or a scalar

Change the value using set()
Example: Zend_Registry


Participant Guide | ZF Fundamentals
239
© 2006-2009 Zend Technologies, Inc.
Slide 239

Copyright © 2006-2009, Zend Technologies Inc.
| 239
Retrieve Values, Construct Objects

To retrieve an entry from the registry, use the getInstance() method

The registry object can be iterated

Construct a registry object using an instance

Utilize it via array object methods, or

Make it static by using the static method setInstance (third code line)



ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
240
Slide 240

Copyright © 2006-2009, Zend Technologies Inc.
| 240
To find out if a particular index in the registry has a value, use the static
method isRegistered():
Querying If An Index Exists
For an index in the registry array object, use
isset():


Participant Guide | ZF Fundamentals
241
© 2006-2009 Zend Technologies, Inc.
Slide 241

Copyright © 2006-2009, Zend Technologies Inc.
|
241
Let’s look at how Zend_Registry is used within the Wiki application
Zend_Registry
Wiki


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
242
Slide 242

Zend_Log


Participant Guide | ZF Fundamentals
243
© 2006-2009 Zend Technologies, Inc.
Slide 243

Copyright © 2006-2009, Zend Technologies Inc.
| 243
Zend_Log
• Zend_Log is a general purpose logging class that supports multiple log
backends, formatting messages sent to the log and filtering messages from
being logged via 4 types of objects:

Log (instance of Zend_Log)
• Object that an application uses most; unlimited number; do not interact; must
contain at least one Writer; can contain one or more Filters

Writer (inherits from Zend_Log_Writer_Abstract)
• Responsible for saving data to storage

Filter (implements Zend_Log_Filter_Interface)
• Blocks log data from being saved; may be applied to an individual Writer or
applied before all Writers; filters may be chained

Formatter (implements Zend_Log_Formatter_Interface)
• Formats the log data before it is written by a Writer
• Each Writer has one Formatter



Logs data to the console, flat files, or a database


Its simple, procedural API reduces the hassle of logging to one line of code and is perfect for cron jobs and
error logs

provides a simple object-oriented interface inspired by log4j

supports extensible output channels

supports extensible output formats


All logs must have at least one Writer

To create a log, all you have to do is instantiate a Writer and then pass it to a Log instance

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
244
Slide 244

Copyright © 2006-2009, Zend Technologies Inc.
| 244
Create a Log (shortcut):
Zend_Log can be used in a simplified way for a single log, can be configured
for multiple logs, and can also be used to log the internal operations of many
Zend Framework classes
Log a Message :
Create a Log



Log A Message

The first parameter of the log() method is a string message and the second parameter is an integer
priority.

The priority must be one of the priorities recognized by the Log instance

Participant Guide | ZF Fundamentals
245
© 2006-2009 Zend Technologies, Inc.
Slide 245

Copyright © 2006-2009, Zend Technologies Inc.
| 245
The Zend_Log class defines the following priorities:
Log Levels
EMERG = 0;// Emergency: system is unusable
ALERT = 1;// Alert: action must be taken immediately
CRIT = 2;// Critical: critical conditions
ERR = 3;// Error: error conditions
WARN = 4;// Warning: warning conditions
NOTICE = 5;// Notice: normal but significant condition
INFO = 6;// Informational: informational messages
DEBUG = 7;// Debug: debug messages



Priority numbers descend in order of importance. EMERG (0) is the most important, and DEBUG (7) is the least
important priority of the built-in priorities.


You may define priorities of lower importance than DEBUG. When selecting the priority for your log message,
be aware of this priority hierarchy and choose appropriately.


These priorities are always available, and a convenience method of the same name is available for each
one.


The priorities are not arbitrary. They come from the BSD syslog protocol, which is described in RFC-3164.


The names and corresponding priority numbers are also compatible with another PHP logging system,
PEAR Log, which perhaps promotes interoperability between it and Zend_Log.

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
246
Slide 246

Copyright © 2006-2009, Zend Technologies Inc.
| 246
Zend_Log vs. Zend_Debug
Debugging with Zend_Log
• Static method Zend_Debug::dump() prints or returns information about an
expression
• Zend_Debug::dump() is best for ad hoc debugging during software
development - requires no initialization, special tools, or debugging environment

Add code to dump a variable and then quickly remove the code
• Consider the Zend_Log component when writing more permanent debugging
code

For example, use the DEBUG log level and the Stream log writer to output
the string returned by Zend_Debug::dump()


Participant Guide | ZF Fundamentals
247
© 2006-2009 Zend Technologies, Inc.
Slide 247

Copyright © 2006-2009, Zend Technologies Inc.
| 247
Writing to Files:
Zend_Log: Writers
Writing to Databases:



A Writer is an object that inherits from Zend_Log_Writer_Abstract


A Writer's responsibility is to record log data to a storage backend

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
248
Slide 248

Copyright © 2006-2009, Zend Technologies Inc.
| 248
Simple Formatting (Zend_Log_Formatter_Simple is the default config):
Zend_Log: Formatters
Formatting to XML:



A Formatter is an object that is responsible for taking an event array describing a log event and outputting a
string with a formatted log line.


Zend_Log_Formatter_Simple is the default formatter. It is configured automatically when you specify no
formatter.


Zend_Log_Formatter_Xml formats log data into XML strings. By default, it automatically logs all items in
the event data array; The code above outputs the following XML
<logEntry>
<timestamp>2007-04-06T07:24:37-07:00</timestamp>
<message>informational message</message>
<priority>6</priority>
<priorityName>INFO</priorityName>
</logEntry>

Participant Guide | ZF Fundamentals
249
© 2006-2009 Zend Technologies, Inc.
Slide 249

Copyright © 2006-2009, Zend Technologies Inc.
| 249
Filtering for all Writers:
Zend_Log: Filters



A Filter object blocks a message from being written to the log


To filter before all writers, you can add any number of Filters to a Log object using the addFilter() method


When you add one or more Filters to the Log object, the message must pass through all of the Filters before
any Writers receives it

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
250
Slide 250

Copyright © 2006-2009, Zend Technologies Inc.
| 250
Zend_Log: Filters
Filtering for a Writer Instance :


Participant Guide | ZF Fundamentals
251
© 2006-2009 Zend Technologies, Inc.
Slide 251

Copyright © 2006-2009, Zend Technologies Inc.
|
251
Let’s look at how Zend_Log is used within the Wiki application
Zend_Log
Wiki


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
252
Slide 252

MOD 10: Model Components of MVC
(Wiki)


Participant Guide | ZF Fundamentals
253
© 2006-2009 Zend Technologies, Inc.
Slide 253

Copyright © 2006-2009, Zend Technologies Inc.
| 253
Model Components in the Wiki Application
• We have already learned about the following components, and examined them
within the Guest Book application
• Now, we will see how they function within a more complex application, the Wiki
application:
Zend_Db_Profiler / _Table / _Adapter / _Select)
Zend_Form
• The application introduces new components related to the Controller layer:
Zend_Acl
Zend_Auth (Adapters, Objects)
Zend_Filter, Zend_Filter_Input
Zend_Validate


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
254
Slide 254

Copyright © 2006-2009, Zend Technologies Inc.
| 254
Model Components in the Wiki Application
• First, we will look specifically at the ZF
components and functionality of the
Model components we examined
previously in the practice applications
• Then, we will look at the new
components the wiki application utilizes


Participant Guide | ZF Fundamentals
255
© 2006-2009 Zend Technologies, Inc.
Slide 255

Copyright © 2006-2009, Zend Technologies Inc.
| 255
A Little More about Zend_Form
• Zend_Form aggregates Elements
and Groups
• Zend_Form provides full and partial validation of the elements

Elements:
• Aggregate metadata
• Contain filter and validation chains

Groups: Display groups
• Aggregate elements purely for display purposes

Groups: Sub-forms
• Aggregate elements related semantically
• Provides namespacing of elements via array notation



Recommendations:

Either pass the form to the view, or pull it from the model within the view

Configure decorators in the view, if customizations are needed (view logic)

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
256
Slide 256

Authorization and Authentication


Participant Guide | ZF Fundamentals
257
© 2006-2009 Zend Technologies, Inc.
Slide 257

Copyright © 2006-2009, Zend Technologies Inc.
| 257
Authentication
What system should you use?
• Whatever suits your site's requirements
How can you authenticate users?
• Databases
• LDAP
• Web Services
• OpenId
• InfoCard
• HTTP Auth/Digest
• Filesystem
•...?


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
258
Slide 258

Copyright © 2006-2009, Zend Technologies Inc.
| 258
Authorization & Authentication
• Zend_Acl ("Permissions")

ACL: Access Control List

Defines access permissions (post-authentication)
• Zend_Auth ("Identity")

Defines whether login is permitted and how authentication is done


Participant Guide | ZF Fundamentals
259
© 2006-2009 Zend Technologies, Inc.
Slide 259

Copyright © 2006-2009, Zend Technologies Inc.
|
259
Let’s look at how Zend_Acl and Zend_Auth are used within the Wiki application
Zend_Acl and _Auth
Wiki


ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
260
Slide 260

Copyright © 2006-2009, Zend Technologies Inc.
| 260
Authorization: Zend_Acl
• Provides lightweight and flexible A
ccess C
ontrol L
ist functionality and
privileges management
• Use ACL to control access to certain protected objects (Resources) by
other requesting objects (Roles)

Resource: an object with controlled access

Role: an object that requests access to a resource

Rights: the privileges a Role has for a given Resource
• Until a developer specifies an "allow" rule, Zend_Acl denies access to
every privilege upon every Resource by every Role

You must whitelist role access to resources - isAllowed() method

You can also blacklist, but this is a less common approach



Example: A bug tracking application…


We want anonymous
users to be able to list
and view
any bug


A bug
is a resource


“list” and “view” are rights
on that resource


The role
is anonymous


Participant Guide | ZF Fundamentals
261
© 2006-2009 Zend Technologies, Inc.
Slide 261

Copyright © 2006-2009, Zend Technologies Inc.
| 261
Zend_Acl: Resources
Creating Resources:
• Zend_Acl_Resource_Interface

A Class implements this interface

Only one method needed,getResourceId()

Zend_Acl_Resource is included with Zend_Acl as a basic,
extendable Resource implementation for developers

Hierarchy structure for assigning rules to resources (simple inheritance)



You can simply use Zend_Acl_Resource rather than extend it, but then it won’t tie directly to your models


Example is sample code from a bug-tracking application…


Note: When you code this feature in the Wiki practice application, it is done by simply extending the Acl
class and defining it programmatically

ZF Fundamentals | Participant Guide
© 2006-2009 Zend Technologies, Inc.
262
Slide 262

Copyright © 2006-2009, Zend Technologies Inc.
| 262
Zend_Acl: Roles
Creating Roles:
• Zend_Acl_Role_Interface

A Class implements this interface

Only one method needed,getRoleId()

Zend_Acl_Role is included with Zend_Acl as a basic, extendable Role
implementation for developers

Multiple inheritance – ability to inherit from multiple Roles provides both
flexibility and complexity



You can simply use Zend_Acl_Role rather than extend it, but then it won’t tie directly to your models

Participant Guide | ZF Fundamentals
263
© 2006-2009 Zend Technologies, Inc.
Slide 263

Copyright © 2006-2009, Zend Technologies Inc.
| 263
Roles: Multiple Inheritance Example
 Defines 3 basic roles: Guest, Member, Admin
 Order within array ($Parents) is important for inheritance
 Other roles (someUser) inherit from these
When specifying
multiple parents for