Zend Framework 1 : Create Model To Access Data From Another Database - php

I am working on a project (Zend 1.12.3) which is already completed by the previous developer and now I am working on a task to show some information using another database (Not current Database) on a specific section of the webpage.
I just want to know how do I create a model for the table to another database which is not currently in use. All the configuration of current database is in the application.ini file.
Should I create a custom query in PHTML file to do this (I know this is a bad coding practice) or is there any other way to show the data from both database?
Thank You :)

Finally I found the solution and it works fine because I need only one model file where I have to access data from another database, Following is my model file i.e Ticker.php
- Ticker.php
class Application_Model_DbTable_Ticker extends Zend_Db_Table_Abstract{
protected $_name = "table_name";
public function __construct(){
$adaptor = new Zend_Db_Adapter_Pdo_Mysql(array(
'host' => 'HOST',
'username' => 'DB_USERNAME',
'password' => 'DB_PASSWORD',
'dbname' => 'DB_NAME'
));
$this->_db = $adaptor;
parent::__construct();
}
public function getTopTickers(){
try {
return $this->fetchAll();
} catch(Exception $e) { die($e->getMessage()); };
}
}

Related

Symfony 1.4 connect to mysql via SSL

I need to change an old Symfony 1.4 application so that it's able to connect to mysql via ssl-connection.
I found a lot about this for Symfony >= 2. But unfortunately not for this dusty one.
For validation purposes I already made it work by editing
./apps/frontend/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Connection.php
$this->dbh = new PDO($this->options['dsn'], $this->options['username'],
(!$this->options['password'] ? '':$this->options['password']), array(PDO::ATTR_PERSISTENT => true));
to
$this->dbh = new PDO($this->options['dsn'], $this->options['username'],
(!$this->options['password'] ? '':$this->options['password']),
array(PDO::ATTR_PERSISTENT => true,
PDO::MYSQL_ATTR_SSL_KEY => '/etc/my.cnf.d/ssl/client-key.pem',
PDO::MYSQL_ATTR_SSL_CERT => '/etc/my.cnf.d/ssl/client-cert.pem',
PDO::MYSQL_ATTR_SSL_CA => '/etc/my.cnf.d/ssl/ca-cert.pem'));
But I wonder if this ugly hack is actually the only solution?
It took me a while to see that this connection class is already overwritten (apps/frontend/lib...).
So I only had to make these variables configurable. There is an option in databases.yml configuration called attributes (doctrine::param::attributes). If you pass non-string keys you can get them with getAttribute.
So at least it works (it's inside the try area of connect-method).
$sslOptionKeys = array(PDO::MYSQL_ATTR_SSL_KEY, PDO::MYSQL_ATTR_SSL_CERT, PDO::MYSQL_ATTR_SSL_CA);
foreach($sslOptionKeys as $sslOptionKey) {
if(array_key_exists($sslOptionKey, $this->pendingAttributes)) {
$pdoOptions[$sslOptionKey] = $this->getAttribute($sslOptionKey);
}
}
$this->dbh = new PDO($this->options['dsn'], $this->options['username'],
(!$this->options['password'] ? '':$this->options['password']),
$pdoOptions);
In databases.yml you will have to type the following (comments help to understand these numbers)
all:
doctrine:
class: sfDoctrineDatabase
param:
dsn: mysql:host=localhost;dbname=db
username: user
password: pass
encoding: utf8
attributes:
#PDO::MYSQL_ATTR_SSL_KEY
1010: /etc/my.cnf.d/ssl/client-key.pem
#PDO::MYSQL_ATTR_SSL_CERT
1011: /etc/my.cnf.d/ssl/client-cert.pem
#PDO::MYSQL_ATTR_SSL_CA
1012: /etc/my.cnf.d/ssl/ca-cert.pem
We found that the attributes array was not working. We had to add an event listener that listened for the doctrine 'doctrine.configure_connection' event and set the properties on the connection directly.
class ProjectConfiguration extends sfProjectConfiguration
{
public function setup()
{
//existing code
$this->dispatcher->connect('doctrine.configure_connection', array(
'ProjectConfiguration','addConnectionSSL'
));
}
static public function addConnectionSSL(sfEvent $event){
$connection = $event->getParameters()['connection'];
/* #var $connection Doctrine_Manager */
$other = $connection->getOption('other');
if(!is_array($other)) $other=array();
$other[PDO::MYSQL_ATTR_SSL_CA] = "PATH_TO_CERT_FILE"; //Set this to actual path. You can also set other properties in the same way.
$connection->setOption('other',$other);
}
}

PHP Page Blank - Not understanding scopes

So, simply put, I feel like this code should work. Literally at this moment I am just trying to create a PHP class that takes in some information and runs a command against the database. I know the command works so it's not that, it something to do with the scope of my variables.
I'm new to PHP, and it's been interesting to handle.
<?php
require __DIR__ . '/../bin/composer/vendor/autoload.php';
$cx = new Customer();
$cx->WriteCxToDB();
class Customer {
public $database = new medoo([
'database_type'=>'mysql',
'database_name'=>'dbname',
'server'=>'localhost',
'username'=>'dbusername',
'password'=>'dbpassword',
'charset'=>'utf8'
]);
public function WriteCxToDB(){
global $database;
if($database->has("customer", [
"OR"=>[
"username"=>"cxusername",
"email"=>"email#gmail.com"
]
]))
{
echo "User already exists";
}else{
$database->insert("customer", [
"username"=>"username",
"keyword"=>"keyword",
"email"=>"email#gmail.com",
"phone"=>"444-444-4444",
"first_name"=>"First",
"last_name"=>"Last"
]);
echo "User added";
}
echo "Done";
}
}
?>
I am using composer and medoo to do this database entry. I know the database code works because I've ran it on it's own and it runs fine.
What I'm struggling with the seems to be the variable $database in the code. The function call works if I remove that variable from the mix. I feel like I'm just not understanding where I am supposed to declare the variable / how to reference it from within / outside the function. Thanks.
As suggested in the previous example you should be using something like this and pass a db connection into the class, extending a base class would allow reuse of the db connection:
private $database;
public function __construct($db_connection = null){
//do stuff or set db
$this->database = $this->db_connect;
}
OR make a method in the class to do it
private function db_connect(){
return new medoo([
// required
'database_type' => 'mysql',
'database_name' => 'name',
'server' => 'localhost',
'username' => 'your_username',
'password' => 'your_password',
'charset' => 'utf8',
]);
}
to check consider catching the errors. Using a unique or primary key on the DB would be a safer way of doing this otherwise you have to do validation and searching on the DB. Add the keys and check for duplicate errors.
if($database->error()){
//deal with return or pass to logging
}
The problem here is the use of global scope. Instead of:
global $database;
if($database->has("customer",
use
if($this->database->has("customer",
you could also consider instantiating $database in the constructor, i.e.
private $database;
public function __construct() {
$this->database = new medoo([args....

access class from other class codeigniter

I have this class that I made as a library in codeigniter
class Openstack{
function __construct($params = array())
{
//namespace OpenCloud;
// note that we have to define these defaults BEFORE including the
// connection class
define('RAXSDK_OBJSTORE_NAME','cloudFiles');
define('RAXSDK_OBJSTORE_REGION','ORD');
require_once('lib/rackspace.php');
// these hold our environment variable settings
define('AUTHURL', 'https://identity.api.rackspacecloud.com/v2.0/');
define('USERNAME', "#####");
define('TENANT', "$$$$$");
define('APIKEY', "asdfasdfasdfasdfasdfasdfasdf");
// establish our credentials
$connection = new Rackspace(AUTHURL,
array( 'username' => USERNAME,
'tenantName' => TENANT,
'apiKey' => APIKEY ));
$ostore = $connection->ObjectStore();...
The problem is, when I call a function using:
public function test_upload(){
$this->load->library('opencloud/openstack');
$this->openstack->upload_file("thisworks.pdf", "static/news/10_12.pdf");
}
I get an error saying the class Rackspace isn't found pointing to the line above where I have new Rackspace...
Within the rackspace.php there is a clas name called Rackspace
class Rackspace extends OpenStack{ ...
I have no idea why it can't find it... I know it's loading the file, because I tried to echo something out in there and it showed up....
Any idea what's happening?
EDIT: At the top of the rackspace.php file there is a
namespace OpenCloud;
I don't have that in my library file class Openstack I made... When I put it in there then I got an error "Non-existent class: Openstack"

Is there zend bootstrap analog in yii?

I want to try db connection to check is db available. In zend I can place my code in boostrap file and wrap it in try catch.
How to implement this in yii?
Is in yii analog of zend boostrap?
UPD: db is mongo, yii extention for working with db is a directmongosuite
Seems that I find appropriate solution:
Need to prohibit auto connect in config file:
'components' => array(
'edms' => array(
'class' => 'EDMSConnection',
'dbName' => 'homeweb',
'server' => 'mongodb://localhost:27017',
'options' => array('connect' => false)
)
)
all controllers should extend one custom controller (BaseController for example).
Need to write own public function beforeAction method where I can add boostrap code.
class BaseController extends CController
{
public $layout = '//layouts/main';
public $navigationMenu = array();
public $breadcrumbs = array();
public function beforeAction($action)
{
try {
Yii::app()->edmsMongo()->connect();
} catch (Exception $e) {
die('Cannot connect to the database server. Please Try again later.');
}
$isGuest = Yii::app()->user->isGuest;
$this->navigationMenu = $this->_getNavigationMenu($isGuest);
return parent::beforeAction($action);
}
In the beforeAction method need to add return true or execute parent's method.
The bootstrap in yii is pretty much the index.php file under public_html or the yiic.php file (for command line applications).
You will probably have to separate the creating of the application instance and running it (by default it does both on 1 line), so you can do your try/catch between the calls.
Just try to fetch the app component, the mongo plugin will throw an exception if it can't open the connection:
try
{
Yii::app()->mongoDb;
}
...
or Yii::app()->getComponent('mongoDb');

make db connection persistent throught zend framework

I'm using zend framework. currently everytime I need to use the db I go ahead and connect to the DB:
function connect()
{
$connParams = array(
"host" => $host,
"port" => $port,
"username" => $username,
"password" => $password,
"dbname" => $dbname
);
$db = new Zend_Db_Adapter_Pdo_Mysql($connParams);
return $db
}
so I would just call the connect() function everytime I need to use the db
My question is...suppose I want to reuse $db everywhere in my site and only connect once in the very initial stage of the site load and then close the connection right before the site gets sent to the user, what would be the best practice to accomplish this?
Which file in Zend should I save $db in, what method should I use to save it (global variable?), and which file should I do the connection closing in?
If you are using the default project structure (with the application, library, tests and public folders), you should use set up the db parameters in application/configs/application.ini
Example application.ini:
[production]
resources.db.adapter = "pdo_mysql"
resources.db.params.host = "localhost"
resources.db.params.username = "testuser"
resources.db.params.dbname = "testdb"
resources.db.params.password = "testpasswd"
resources.db.isDefaultTableAdapter = true
In this way zend framework will automatically open and close the connections to the database and you can use the Zend_Db_Table or Zend_Db_Table_Abstract classes to query your tables easily, for example, to retrieve the student's data for a given SSN you could write a model (application/models/Student.php) that looks something like this:
<?php
class Model_Student extends Zend_Db_Table_Abstract
{
protected $_name = "student";
public function fetchRowsBySSN($ssn)
{
$select = $this->select();
$select->where('ssn = ?', $ssn);
return $this->fetchRow($select)->toArray();
}
}
As you can see there's no need to open/close the connection and you get an associative array with the fields and values of the student record.
Your best best may be to move all of your db connection code into a separate class in which you can set a static $db var.
protected static $_db;
public static function connect()
{
if (self::$_db == null) {
$config = Zend_Config_Xml(); // whatever you'd use
self::$_db = Zend_Db::factory($config->database);
self::$_db->setFetchMode(Zend_Db::FETCH_OBJ);
self::$_db->query('SET NAMES UTF8');
Zend_Db_Table::setDefaultAdapter(self::$_db); // optional
}
return self::$_db;
}
public static function close()
{
if (self::$_db != null) {
self::$_db->closeConnection();
}
}
According to Zend:
Normally it is not necessary to close a database connection. PHP automatically cleans up all resources and the end of a request. Database extensions are designed to close the connection as the reference to the resource object is cleaned up.
However, if you have a long-duration PHP script that initiates many database connections, you might need to close the connection, to avoid exhausting the capacity of your RDBMS server. You can use the Adapter's closeConnection() method to explicitly close the underlying database connection.

Categories