I am new to Zend Framework and I have installed it on my local server.
Below is my application.ini:
[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.params.displayExceptions = 1
resources.db.adapter = "pdo_mysql"
resources.db.params.dbname = "zendy"
resources.db.params.host = "localhost"
resources.db.params.username = "root"
resources.db.params.password = ""
I have created a database named zendy and created a table named country with two rows.
I have created country.php in my models folder and below is my code for it:
class Application_Model_country extends Zend_Db_Table_Abstract
{
protected $_name = 'country';
protected $_primary = 'id';
}
Below mentioned code is my indexController.php:
class IndexController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
$c = new Application_Model_country();
$this->view->country=$c->fetchAll();
}
}
But it throw an error in browser.
An error occurred
Application error
I have tried to debug from ErrorController.php it display error like:
protected 'message' => string 'Primary key column(s) (id) are not columns in this table ()' (length=59)
But while I have created the country-table in my database I've already applied a primary key.
Can anyone please help me out why this error happens? Is my ZF-project connected to the database?
Or do i miss anything?
Related
I have a project with Zend Framework and i trying to rewrite this peoject on Zend Framework 2. In old project i have some environment dependent settings in application.ini
[Prod]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
appnamespace = "Application"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.params.displayExceptions = 1
theme = Test
copyright = TestText
resources.db.adapter = pdo_mysql
resources.db.params.host = 127.0.0.1
resources.db.params.username = root
resources.db.params.password = adm$123
resources.db.params.dbname = test;
I controller some value from aplication.ini has retrived.
$bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap');
$aConfig = $bootstrap->getOptions();
$this->view->assign('theme', $aConfig['theme']);
$this->view->assign('copyright', $aConfig['copyright']);
I download skeleton-application with Zend Framework 2 , add new module. But how I can do similar in my new project? Where and how I should describe settings from old project? How I can retrieve it?
You can easily use the AbstractOptions class for your ZF2 module. Let 's assume your ZF2 module is called application. So it 's stored in /module/Application/ folder.
First you need the ModuleOptions class under /module/Application/src/Options/. In this class you can write down all your settings you need for your module. For example reasons I only write the copyright member in the class.
declare('strict_types=1');
namespace Application\Options;
use Zend\StdLib\AbstractOptions;
class ModuleOptions extends AbstractOptions
{
protected $copyright = 'my copyright';
public function getCopyright() : string
{
return $this->copyright;
}
public function setCopyright(string $copyright) : ModuleOptions
{
$this->copyright = $copyright;
return $this;
}
}
Further you need a factory for your module options class. This factory could look like the following example.
declare('strict_types=1');
namespace Application\options\Factory;
use Application\Options\ModuleOptions;
use Interop\Container\ContainerInterface;
class ModuleOptionsFactory
{
public function __invoke(ContainerInterface $container) : ModuleOptions
{
$config = $container->get('config');
$options = new ModuleOptions(isset($config['my_settings']) ? $config['my_settings'] : []);
return $options;
}
}
Basicly that 's all you need. Just wrap it up in your module.config.php like the following example.
...
'service_manager' => [
'factories' => [
ModuleOptions::class => ModuleOptionsFactory::class,
]
],
'my_settings' = [
'copyright' => 'another copyright text',
]
The ModuleOptions class takes the my_settings array from your module.config.php and makes it accessable wherever a service locator is.
Example for use in a controller
For example you could use the ModuleOptions class in a controller factory like in the following example.
class IndexControllerFactory
{
public function __invoke(ContainerInterface $container)
{
$container = $container->getServiceLocator();
$options = $container->get(ModuleOptions::class);
return new IndexController($options);
}
}
Your IndexController class looks something like this. In this example we avoid calling the service locator in the controller itself because this is a bad practice. We just pass the options as a argument in the constructor.
class IndexController extends AbstractActionController
{
protected $options;
public function __construct(ModuleOptions $options)
{
$this->options = $options;
}
public function indexAction()
{
return [
'copyright' => $this->options->getCopyright(),
];
}
Enjoy! ;)
In laravel there are some config files which could be controlled / set with .env file for developing. My question is it possible to set the production values through a db table for example a settings_mail and settings_app table. I need this so that the admin when nessesery could change Some value in a view and doesn't need entering the code
Create a settings table, like this:
name
value
category
hostname
smpt.example.com
mail
address
San José
general
Create a setting model based in table structure:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Setting extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'settings';
protected $name = '';
protected $value = '';
protected $category = '';
}
Load the settings to be accessible at entire application:
// app/Providers/AppServiceProvider.php
public function boot(){
$settings = App\Setting::lists('name', 'value')->all();
config()->set('settings', $settings);
}
Now, get some config:
$address = config('settings.address');
I'm trying to change my database connection depending on who is trying to log in to my page.
What I need is a way to save the correct db name so its accessible by all my controllers.
Using a session would work, but I doubt its safe and/or good practice.
If I could set a variable in the AppController from my AccountsController that would be perfect. but basically any way that enables me to share a variable between all controllers.
In my AccountsController I query a standard database for the correct name. then I use configure::write('CompanyDB', $myDbVar). this work fine for this controller, but I cant use configure::read('CompanyDB') in any other controllers.
In my AppModel i have a construct fucntion that sets the db connection depending on the value inside configure::read('campanyDB') as mentioned before, I need to use configure::write('CompanyDB',$myDbVar) in all my controllers for this to work.
In my Account Model I set the $specific=true. this tells the AppModel that it should use the construct and change the db connection.
class AccountsController extends AppController {
public $helpers = array('Html', 'Form','Js');
public $components = array('RequestHandler');
var $uses = array('User', 'Company');
public $name = 'Accounts';
public $myDbVar='coolbeans';
public function beforeFilter() {
parent::beforeFilter();
Configure::write( 'companyDB',$this->myDbVar);
}
}
class AppModel extends Model {
var $specific = false;
function __construct($id = false, $table = null, $ds = null) {
if ($this->specific) {
// Get saved company/database name
$dbName = Configure::read('companyDB');
// Get common company-specific config (default settings in database.php)
$config = ConnectionManager::getDataSource('companySpecific')->config;
// Set correct database name
$config['database'] = $dbName;
// Add new config to registry
ConnectionManager::drop('companySpecific');
ConnectionManager::create('companySpecific', $config);
// Point model to new config
$this->useDbConfig = 'companySpecific';
}
parent::__construct($id, $table, $ds);
}
}
class Account extends AppModel {
public $primaryKey = '_id';
//var $useDbConfig = 'mongo';
var $specific = true;
.....
}
Probably best bet would be to go with a Configuration file:
Reading and Writing Configuration Files:
http://book.cakephp.org/2.0/en/development/configuration.html#reading-and-writing-configuration-files
The basic idea is, you create a file in your Config/ directory with settings for your app, then, in the bootstrap, you load that config file, which makes any of those variables available anywhere in the app.
Example file: Config/dbconnections.php
<?php
$config = array(
'MyAppDBs' => array(
'company1' => 'connectionName',
'company2' => 'differentConnectionName
)
);
In your bootstrap file:
Configure::load('dbconnections');
Anywhere in your App:
$whatever = Configure::read('MyAppDBs.companyDB');
I think if you do this
configure::write('CompanyDB', $myDbVar);
in your appController then you can access it in any controller using
configure::write('CompanyDB',$myDbVar);
since all controller inherits appController.
i am using a modular architecture with Zend framework, and i want to use the module specific database configuration such that each module's model employs its own database configuration.
This is my sample application architecture:
application
modules
admin
controllers
models
DbTable
Users.php
views
configs
module.ini
configs
application.ini
From the above architecture, i have the module "admin" and i have specified its database configuration in admin/configs/module.ini like:
resources.db.adapter = "pdo_mysql"
resources.db.params.host = "localhost"
resources.db.params.username = "*****"
resources.db.params.password = "*****"
resources.db.params.dbname = "********"
Now I want to use this configuration in the models of "admin" module.
FYI, Iam instantiating the model in the "admin" module's controller like:
$admin = new Admin_Models_DbTable_Users();
$admin_users = $admin->fetchUsers();
And in the "admin" module's model, i am executing the queries like:
public function fetchUsers()
{
$sql = "select * from users";
return $this->getAdapter()->fetchAll($sql, array(), Zend_Db::FETCH_OBJ);
}
How can i load the database configuration in admin/configs/module.ini in my "admin" module's database adapter such that it uses that configuration? Do i need to use Zend Registry or set any options in admin module's bootstrap file ?
You should use multidb resource plugin. In short, in you application.ini you should setup all your databases:
resources.multidb.employees.adapter = PDO_MYSQL
resources.multidb.employees.host = localhost
resources.multidb.employees.username = zend
resources.multidb.employees.password = zend
resources.multidb.employees.dbname = zend
resources.multidb.employees.default = true
resources.multidb.employees1.adapter = "PDO_SQLITE"
resources.multidb.employees1.dbname = APPLICATION_PATH "/../data/db/employeesdb.db"
Then in you Bootstrap.php you should save them into registry:
public function run()
{
$resource = $this->getPluginResource('multidb');
Zend_Registry::set('news', $resource->getDb('employees1'));
Zend_Registry::set('employees', $resource->getDb('employees'));
parent::run();
}
And at last in your db model class you should write:
/**
* Db name.
*
* #var string
*/
protected $_use_adapter = 'employees1';
and (this part can be put to some abstract class which extends Zend_Db_Table_Abstract and will be parent for all your db models classes):
public function __construct($config = null)
{
if(isset($this->_use_adapter)){
$config = $this->_use_adapter;
}
return parent::__construct($config);
}
i am following a different approach, as suggested by one of my friends:
In the module's bootstrap file, i am setting the module's db adapter into the Registry, and in the module's model file, i am getting the module's db adapter from the registry using a custom method: getAdapter()
Code in ....application/modules/admin/Bootstrap.php
protected function _initAutoload()
{
$configuration = new Zend_Config_Ini(
APPLICATION_PATH . '/modules/admin/configs/module.ini',
'production'
);
$params = $configuration->resources->db->params->toArray();
$DB = new Zend_Db_Adapter_Pdo_Mysql($params);
Zend_Registry::set('DB',$DB);
}
Code in ...application/modules/admin/DbTable/Users.php
public function getAdapter()
{
$registry = Zend_Registry::getInstance();
return $registry['DB'];
}
So now the $this->getAdapter() in admin module's fetchUsers() method will have the db adapter of "admin" module. :)
FYI: my friend also wanted to do this. He set a default adapter in the application.ini. Then in each zend_db model where he wanted to use another database, he changed the schema configuration. He said it was the easiest. Then his db model already had the authentication and host, and he just overwrote the database and table. Definitely consider this option; sorry I don't have any links or examples.
i have 3 moulde like blow ,
application
|
modules
|
default
|---models
|--views
|--forms
|--controller-
|-indexController
|-errorController
admin
|---models-
|-user.php
|--views
|--forms
|--controller--
|-userController
cars
|---models
|--views
|--forms
|--controller
bootstrap.php
and in my appliction.ini
i have this config
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.modules = ""
and in my bootsrap file i have this autoloader
$modelLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH ));
so i can not access to my models class in userController and other controllers
i have this code in my userController
$userModel = new admin_Model_Users();
but i got error can not find this class
and this class is in user.php
class admin_Model_Users extends Zend_Db_Table_Abstract
{
public function getListUser() {
}
}
someone may help where is my wrong and how could fix this problem?
Get rid of
$modelLoader = new
Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH ));
and add
Bootstrap.php in you module:
class Admin_Bootstrap extends Zend_Application_Module_Bootstrap
{
}
also name your class Admin_Model_Users and use it accordigly where appropriorate.
Use capital "U" in the filename, capital "A" in the class name. I mean names should be consistent and in accordance to ZF guidelines.
Also in ini file:
change entry to
resources.modules[] =
Try the following:
class admin_Model_Users extends Zend_Db_Table_Abstract
Should become
class Models_UsersAdmin extends Zend_Db_Table_Abstract
$userModel = new admin_Model_Users();
Should become
$userModel = new Models_UsersAdmin();
Update
in you're application.ini file where you register you're namespaces add the following line:
autoloaderNamespaces[] = "Models" ( or register the namespace "Models" at bootstrap )
;define modules after controller in application.ini file
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"