This video is the first in a series on Zend_Db. I start with a looking at insert and read using the Zend_Db_Table classes with a bit of Zend_Db_Select thrown in at the end. Next week will be a followup with update and delete with the help of a custom route, some view partials and a few more additions to our service layer. I’m not a fan of putting business logic in the same object as a class belonging to the Table Data Gateway pattern, so I’ve created a custom UserService object to help seperate the view and model layers. This would also be in keeping if you had multiple service layers (for example, a database, a couple RSS feeds and a couple of web services) and wanted to keep their business logic and querying outside of the Controller. I don’t bother with Zend_Form since it’s configuration heavy and only really interesting in conjunction with validators, however it would fit in perfectly as an extension to this project. The code can be downloaded for this and next weeks episode to help you follow along.
Zend_Db Insert and Read
Description
This video is the first in a series on Zend_Db. I start with a looking at insert and read using the Zend_Db_Table classes with a bit of Zend_Db_Select thrown in at the end. Next week will be a followup with update and delete with the help of a custom route, some view partials and a…
Tags
database, Databases, persistence layer, service layer, table data gateway, zend_db_table

What do you think of skipping the service class in favor of keeping table-specific logic in the table class itself?
so more like:
$users = new UsersTable();
$users->CreateTestUser();
Thinking after a few tables, keeping all the CRUD in a single class might be a bit unwieldy, and this is the other approach I’ve seen while researching Zend_Db.
Hey James,
that’s a great point, however often when you’re managing relationships between tables (e.g. a user with many posts, a post with many tags), then the relationships don’t belong in either table. The “service” layer is a very light version of what Evans’ would call an aggregate root, or an entry point into a domain. The thinking here is that you want to encapsulate the complexity of multiple Zend_Db_Table’s (and perhaps other non-database related data sources) in a class that hides the implementation details from its consumers. Also, if you’re just doing simple CRUD, then the Active Record pattern (implemented in Doctrine as well as Propel) makes more sense since it really works well in handling the simple saves on one table. This pattern falls apart when you need to do joins that are more dynamic, or you need to start aggregating or doing reporting against larger data sets.
my 2 cents.
Interesting. Perhaps a mixture of the two styles would work, simple stuff in the table ($user->CreateTestRecord()), and more complicated / higher level work in the service layer?
Though a lot of the simple operations (and some more complex ones, as I understand it) should be handled by Zend_Db_Table_Abstract’s magic functions.
Just thinking in-text here… Assuming you declare all the available tables in the service layer, you could make them publicly available and still have the table functionality ($service->users->CreateTestUser()), while also having the ability to just load the one particular table you need if your action is only working on one table (say, updating a user’s email address).
Just throwing this out there, I don’t quite have the experience to dictate either way.
Thanks for posting the video, your casts are very helpful.
very interesting, to have some kind of adapter thing between .. thnx
there’s a wider article about service layers and zend here:
http://www.angryobjects.com/2009/03/30/writing-robust-php-backends-with-zend-framework/
albeit without the actual demo or code
just to add, these casts are excellent
very interesting.
looking forward for the next webcast about zend_db
I’m using netbeans if that makes any difference to this problem and maybe my installation needs to be altered, but I’m not sure how. I keep getting the Fatal error: Class ‘UsersTable’ not found when I try the first test.
I’m having the same problem as Russ. Is there a way to make it autodetect things in my models folder?
More info:
I already have my include path set to application/models. I think the problem might have something to do with the fact that when you use Zend_Loader it gives you a warning saying it’s outdated, so we’re using Zend_Loader_Autoloader. I had to add a namespace of App_ to the autoloader to get it to load things in library/app, and I’m guessing it’s the same for models, but since there’s no namespace involved it just doesn’t try it. I’m not sure.
I finally figured out my problem. I went through and did the 1.8 installation and then followed the new quick start guide. In that guide, they use the namespace of Default_Model_ for all of the model classes. Once I updated the respective classes and controller, everything worked great.
I’m using the ‘latest version of zend framework 1.9,
if I want to use the configurations included in the db application.ini what should include in __construct and bootstarp ??
thanks
Good work here!!!!
I´m following the example but i can’t instanciate App_UserService in the controller it throw me a error of class not found . I´m using Zend 1.9. Does anyone have this problem?? Need same help here…. thank you
Spinto
hey Spinto, it sounds like your not registering your namespace in the bootstrap file. I’ve written about it here on the forum:
http://www.zendcasts.com/forum/post/65/#p65
Hi im having the same issues with the ‘class not found’. Im using zend 1.8 and have tried Jons method with no avail. I understand the namespace for App in the library folder but its looking for the UsersTable.php in the /library/App/UserService.php when the Userstable.php is located in the modules folder. Any ideas of where I have gone wrong?
Thanks for great tutorials.
ZF is very new for me, so therefor I have this newbee question:
Why a service layer? Why not put this code for select, insert, update … in the Model?
Sorry for this dump question
Regards, Magnus
Hi Magnus,
The model is a fine place to do this depending on the size of your application. The use of a service layer is likely to make sense if your models are complex or are linked to multiple data sources. In such an instance, you might want to create a service layer that acts as a facade and brokers the commits across multiple persistence mechanisms.
Hi Jon I’m using the framework 1.9 and following your video tutorial I always get the following error: “Fatal error: Class ‘UsersTable’ not found in C: \ Sites \ zendcast \ library \ App \ UserService.php on line 23″. After reading some articles, I resolved this problem renaming the model’s class: “Model_UsersTable”. Is it correct? Can you tell me if I should do something else?
thank you for your attention
Nicola
Hi Nicola,
Model_* is the default namespace for models in the Zend Framework. I believe I got around it by including the ‘models’ folder in my include paths for that particular video.
Thanks Jon, I use Zend Studio 7.0, when I create a new Zend Framework project, a bootstrap file is generated.I modified it according your tutorial, but when I include the path of the “models” I always get the above error “Fatal error: Class’ UsersTable ‘not found in C: \ Sites \ zendcast \ library \ App \ UserService.php on line 23 “. Where am I wrong? As I wrote you in my last post, I have to rename the model’s class in order to solve the problem.
I attach you the bootstrap file:
bootstrap()
->run();
?>
error_reporting(E_ALL||E_STRICT);
ini_set(‘display_error’,’1′);
// Define path to application directory
defined(‘APPLICATION_PATH’)
|| define(‘APPLICATION_PATH’, realpath(dirname(__FILE__).”/../application/” ));
// Define application environment
defined(‘APPLICATION_ENV’)
|| define(‘APPLICATION_ENV’, (getenv(‘APPLICATION_ENV’) ? getenv(‘APPLICATION_ENV’) : ‘production’));
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . ‘/../library’),realpath(APPLICATION_PATH . ‘/models/’),
get_include_path()
)));
/** Zend_Application */
require_once ‘Zend/Application.php’;
// Create application, bootstrap, and run
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . ‘/configs/application.ini’
);
$application->bootstrap()
->run();
For those who are having Fatal error: Class ‘UsersTable’ error, add include path to /public/index.php
set_include_path(
APPLICATION_PATH . ‘/models’
. PATH_SEPARATOR . get_include_path()
);
Hi Anarxi, I added this code in index.php:
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . ‘/../library’),realpath(APPLICATION_PATH . ‘/models/’),
get_include_path()
)));
As you can see the path for the models already exist. Do you have any other ideas?
Thank you.
nicola,
Try adding this to your bootstrap php file:
protected function _initAutoload()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
‘namespace’ => ‘App’,
‘basePath’ => dirname(__FILE__),
));
return $autoloader;
}
then UserService.php would be
$this->users = new App_Model_UsersTable();
and
UsersTable.php would be
class App_Model_UsersTable extends Zend_Db_Table_Abstract
Jon: I’m wondering how one would fetch db table data and transform it into JSON data object at page load. Is there a library function for such a task?
Hi didymus, you have try with JQuery?
Jon, yes, I’m using JQuery following your tutorial on Zend View Helpers with AJAX. The flickr object is not recognized by the helper. I tried accessing it from the view and tried passing it through to the helper as input parameter but in either case I found it to be inaccessible.
Oops, I just posted comment to wrong article… With respect to converting database feed into JSON using JQuery, I’m not sure how to do that but maybe there is an article out there I can find. Do you prefer JQuery for this sort of task? I did find this one that uses php’s json_encode: http://net.tutsplus.com/tutorials/php/asynchronous-comments-with-jquery-and-json/
Brett & Nicola: Thanks for the comments on the “class table not found” error. Brett’s last suggestion works (along with Jon’s blog post article on namespace registration). I think that most people forget to add the “Model_” to the class name and any calls to it.
Great screencasts – one of the reasons I still haven’t switched to a different framework, or programming language
The Zend documentation in Zend Framework 1.10 shows how to use a mapper with Zend_Db_Table. Is this analogues to the services you use in this screencast?
The default directory structure seems to be:
application/models –
application/models/DbTable – table classes
application/models/mappers – mappers (this part is from Rob Allen’s getting started tutorial)
What is user in db exists?
public function NewUser($nick, $pass, $mail, $name, $lname, $loc, $fg, $gt){
$params = array(
‘username’ => $nick,
‘password’ => md5($pass),
‘mail’ => $mail,
‘fname’ => $name,
‘lname’ => $lname,
‘date’ => strftime(“%Y/%m/%d”),
‘location’ => $loc,
‘fgame’ => $fg,
‘gtype’ => $gt,
‘acccreated’ => strftime(“%Y/%m/%d”),
‘ban’ => ’0′
);
$this->users->insert($params);
}
how i can check for that info, i have that nick in db or its free to use?
I am using Zend 1.10 and this code is no longer working.
@Pip
you should configure code for 1.10
.
@Pip to ZF 1.10
rename UsersTable into Application_Model_UsersTable
hey all
i hate to beat a dead horse
but i think between all the updates in the ZF
and the orig posting of this vid
its been a trying time for me to get rid of this error:
Fatal error: Class ‘Application_Model_Press’ not found in /var/local/virtuals/www.acemetrix.com/library/AM/Db/PressService.php on line 32
first off im running ZF1.8
my include path looks like this:
/path/to/library:/path/to/application/models
ive tried adding this to my bootstrap (according to brett above):
protected function _initAutoload()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
‘namespace’ => ‘Application’,
‘basePath’ => dirname(__FILE__),
));
return $autoloader;
}
ive also tried adding this to my bootstrap (according to http://www.zendcasts.com/forum/post/65/#p65)
protected function _initAutoload()
{
$moduleLoader = new Zend_Application_Module_Autoloader(array(
“namespace” => “”,
“basePath” => APPLICATION_PATH));
/** auto load */
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);
return $moduleLoader;
}
ive tried cross referencing with the code jon has uploaded up on google
but obviously im missing something
pls help!
thanks
Reply to toy
My directory structure is models and models/DbTable and NOT “Db” like yo seem to have … by default, that is. Also ZF 1.10, by default there is no “Application” prefix so the model class starts with “Model_…” … this might change depending on your _initAutoLoad() function.
hey patryk
thanks for your reply
actually my dir structure is NOT
models/db it is the same as yours
i think you are referring to this:
/var/local/virtuals/www.acemetrix.com/library/AM/Db/PressService.php
which i should have generalised it as the path to db service layer
which resides in the library
ie, /path/to/library/MyCustomLib/Db/dbServiceLayer.php
which is how jon’s example here is setup
one last thing
yes you are correct about me running ZF1.10 not ZF1.18
i made a typo there
so if the Nayre posting above says the foloowing
“rename UsersTable into Application_Model_UsersTable”
which is now what you are telling me is wrong?
its now become pretty clear to me
that my issue is is that the when the service layer is called
the model for my object ‘press’ is not in the include path
or has not been loaded
which is weird since
1) if i print out the path
its has application/models in the path
and
2) i thought ZF 1.10 was supposed to autoload the models
nad if not then the init autoload statement would take care ofit
am i confusing the issue here?
@patryk
hi again –
i took out the _initAutoload function
it seemed redundant
and i changed Application_Model_Press to Model_Press
and my press service layer is still returning:
Fatal error: Class ‘Model_Press’ not found in
/path/to/library/MyLib/Db/PressService.php
im wondering why ZF 1.10 is not autoloading my model…
Reply to toy.
By default ZF 1.10 should autoload files in the directories: application/models and application/models/DbTable. The class prefix Model_SomeName and Model_DbTable_SomeName should be defined in application/models/SomeName.php and application/models/DbTable/SomeName.php. (the class Model_DbTable_SomeName should extend Zend_Db_Table_Abstract).
If you have defined a namespace in _initAutoload (in Bootstrap.php) the prefixes will change to YourNamespace_Model_SomeName and YourNamespace_Model_DbTable_SomeName.
You can change your models directory in the application.ini file with this line of code:
resources.frontController.modelsDirectory = APPLICATION_PATH “/my_models”
You can probably also add any directory to autoload.
Hope this helped to resolve your problems.
hey patryk
as it turned out –
my models were NOT being autoloaded
for whatever reason
and this is what i ended adding that wroked:
protected function _initAutoload()
{
$loader = new Zend_Application_Module_Autoloader(array(
“namespace” => “”,
“basePath” => APPLICATION_PATH));
// autoload
$loader->addResourceType(“model”, “models”, “Model”);
}
If you get Fatal error: Class ‘UsersTable’ error, on ZendFramework 1.11, update the include path in /public/index.php to be like this
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . ‘/../library’),
realpath(APPLICATION_PATH . ‘/models’),
get_include_path(),
)));
It works for me