Problems connecting to db using Zend db as standalone - php

I am migrating from ZF1 Zend_db to ZF2. I have problems connecting to the db and making a simple query. Appreciate if someone can guide me along. Below is my code.
This is how i connect to db
use Zend\Db\Adapter\Adapter;
$dbo = new Zend\Db\Adapter\Adapter(array(
'driver' => 'pdo_mysql',
'database' => DB_PREFIX.DB_NAME,
'username' => DB_USER,
'password' => DB_PW
));
Zend_Registry::set('db', $dbo);
This isan example how i use it.
$this->dbo = Zend_Registry::get('db');
function createData($message,$tags,$userid,$imgsrc){
$data= array(
'message' => $message,
'tags' => $tags,
'imgsrc' => $imgsrc,
'createdtimestamp'=>new Zend_Db_Expr('NOW()'),
'userid' => $userid);
$this->dbo->insert('mydata', $data);
return $this->dbo->lastInsertId();
}
I have an error. That is $dbo does not have select(),insert() methods etc. I could did it in ZF1 zend db.
Example of error message i received:
Fatal error: Call to undefined method
Zend\Db\Adapter\Adapter::select() in

You seem to think that ZF2 and ZF1 are (and should be) class-compatible. The problem is, they're not - at least in regards to Zend\Db\Adapter. That one in ZF2 is much more concise: while it has query method, its main responsibility is abstracting the DB connection itself.
I suppose what you're looking for is located in Zend\Db\Sql area. Assuming you have your DB connection in $dbo, you can create an Sql object based on it:
use Zend\Db\Sql as Sql;
$sql = new Sql\Sql($dbo);
... then create another object (of Zend\Db\Sql\Insert class):
$insert = $sql->insert('mydata');
$insert->values([
'message' => $message,
'tags' => $tags,
'imgsrc' => $imgsrc,
'createdtimestamp'=>new Sql\Expression('NOW()'),
'userid' => $userid
]);
... then use this object in query:
$insertString = $sql->getSqlStringForSqlObject($insert);
$results = $dbo->query($insertString, Adapter::QUERY_MODE_EXECUTE);

Related

Symfony 5 Cannot autowire argument $Driver for a dynamic database connection

I am currently facing a problem, I explain myself. For my project I'm trying to make a dynamic connection to a database (I have 2 virtual machines with a different IP but with the same identifiers and tables with MSSQL database engine (SQLSRV)).
I try something like this ->
use Doctrine\DBAL\Driver\SQLSrv\Driver;
/**
* #Route("/testconnection", name="test_connect")
*/
public function testConnection(Driver $Driver){
$connectionParams = array(
'dbname' => 'job',
'user' => 'sa',
'password' => 'Lasernet#2020',
'host' => '192.168.1.34',
'driver' => 'pdo_sqlsrv',
);
$conn = $Driver->connect($connectionParams);
dd($conn);
}
Error message
Cannot autowire argument $Driver of "App\Controller\HomeController:testConnection()": it references class "Doctrine\DBAL\Driver\SQLSrv\Driver" but no such services exists.
Error message
But the problem is that Symfony sends me back an error that I find hard to solve/understand.
If someone has a solution to my problem/success to make a dynamic connection to databases.
If you need more information tell me.
The error message says it. No such service exists.
You must define the Doctrine\DBAL\Driver\SQLSrv\Driver class as a symfony service in your public/services.yaml to autowire it.
Update your public/services.yaml with:
services:
Doctrine\DBAL\Driver\SQLSrv\Driver:
autowire: true
But why you will autowire this class? The same behaviour you can get with
public function testConnection(){
$Driver = new Driver();
$connectionParams = array(
'dbname' => 'job',
'user' => 'sa',
'password' => 'Lasernet#2020',
'host' => '192.168.1.34',
'driver' => 'pdo_sqlsrv',
);
$conn = $Driver->connect($connectionParams);
dd($conn);
}
And if you have no really dynamic values in your connection params like $connectionParams['dbname'] = 'sqldb'.$i, better to use the doctrine dbal config and get the connection with $this->getDoctrine()->getConnection('name'); in your controller.
Symfony Docs

Correct way to edit a database service after first initiation

I use two different database services in my Phalcon application.
db: Global database with system-wide data, including accounts and users
db_data: This database hosts customer-specific data. The database-name is different for each customer/account. This is determined when the customer sign in.
This works in the web application, when I have one account active. Now I have a cronjob, that is going to loop through a table in the global "db" database. And after it is going to connect to the specific "db_data" database.
This works for the first account, but after this it will not connect to the new database. It still use the first initiated database.
The db_data service is a shared service in the services.php:
$di->set('db_data', function () use ($config, $di) {
if(!$di->getCore()->getAccount()) {
throw new \MyNamespace\Exception(_('Account is not set. Can not load account database.'));
}
$eventsManager = $di->getShared('eventsManager');
$dbListener = new \MyNamespace\Module\Core\Helper\Model\DatabaseListener();
$eventsManager->attach('db_data', $dbListener);
$connection = new \Phalcon\Db\Adapter\Pdo\Mysql(array(
'host' => $config->database->host,
'username' => $config->database->username,
'password' => $config->database->password,
'dbname' => $config->database->data_dbname_prefix.$di->getCore()->getAccount()->id,
'name' => 'data',
));
$connection->setEventsManager($eventsManager);
return $connection;
}, true);
In the first model in "db" i have the following in the initialize() function:
$this->setConnectionService('db');
In the second model in "db_data" i have the following in the initialize() function:
$this->setConnectionService('db_data');
Here is an example of the cron PHP-file:
$screens = \MyNamespace\Module\DigitalSignage\Model\Screen::find(array(
'conditions' => 'deleted_at IS NULL',
));
foreach($screens as $screen) {
$console->getDi()->getCore()->setAccount(\MyNamespace\Module\Core\Model\Account::findFirst('id='.$screen->account_id));
$campaign = \MyNamespace\Module\DigitalSignage\Model\Campaign::findFirst(array(
'conditions' => 'id = :id: AND account_id = :account_id: AND deleted_at IS NULL',
'bind' => array(
'id' => $screen->digitalsignage_campaign_id,
'account_id' => $console->getDi()->getCore()->getAccount()->id,
),
));
var_dump($campaign);
}
What is the correct way to change the database service parameteres after first initiation?
Phalcon version: 3.2.2 PHP version: 7.0.22

Laravel Guzzle Request gets wrong DB Connection

I am trying to make a request from one Laravel project to another. The issue that I am getting is that the second Laravel is using the first Laravel Database Connection. So it is complaining that a table does not exist.
Here is the code that I am using.
$data = ['test' => 'foobar'];
$client = new \GuzzleHttp\Client();
$url = getenv('API_BASE') . 'stock-list';
$res = $client->request('POST', $url, [
'headers' => [
'X-Public' => getenv('API_PUBLIC'),
'X-Hash' => ApiService::Encrypt(getenv('API_PRIVATE'), json_encode($data)),
],
'json' => $data,
'http_errors' => false,
]);
echo "<pre>" . print_r($res->getBody()->getContents(), true) . "</pre>";
Has anyone ever come across something like this?
The way to fix this as I am running both Laravel projects on the same server, is to change the environment variable names in the .env file.
DB_DATABASE=XXXX
becomes
XXX_DB_DATABASE=XXXX
This needs to be done on one of the Laravel setups then it all works properly.
You can change the default db connection runtime like this:
So let's say you have
1 security db with credentials that is the default db design time.
1 or more databases containing data for 1 or more users.
You log in using the security db and based on the user change the default db to the data db.
config(['database.connections.data' => array(
'driver' => 'sqlsrv',
'host' => $connection['Database_Server'],
'database' => $connection['Database_Name'],
'username' => $connection['Database_User'],
'password' => $connection['Database_Password']
)]);
DB::setDefaultConnection('data');
If you don't need such flexibility you can define the connection per model:
class A extends Model {
protected $connection = 'security';
protected $table = 'A';
}

PDO does not recognize column with special character

I'm trying to create an application with SimpleMVC (PHP Framework) and in the database there is a column with the name "contraseña".
When trying to make any query in this column, the PDO returns this error:
SQLSTATE [HY093]: Invalid parameter number: parameter was not defined
There is how to make the PDO recognize special characters?
Controller:
$servidor = array(
'cuenta' => $usuario,
'contraseña' => $senha,
'ipRegistro' => $ip,
'apodo' => $apelido
);
$this->_model->insert_server($servidor);
Model:
public function insert_server($data) {
$this->_db->insert("cuentas",$data);
}
Link to the SimpleMVC Framework: PHP Framework - SimpleMVC
Wrap the column bame in backticks, like so:
$servidor = array(
'cuenta' => $usuario,
'`contraseña`' => $senha,
'ipRegistro' => $ip,
'apodo' => $apelido
);
Might be something worth mentioning to the SimpleMVC developers.

Zend Framework Firebird Example

I am new to Zend. I'm using Zend 1.11 and trying to successfully connect to a Firebird database. As far as I can tell I have all the php_interbase stuff enabled. I see the ZendX firebird adapter, but I still get this message
Warning: include_once(Zend\Db\Adapter\Php\Firebird.php)
[function.include-once]: failed to open stream: No such file or
directory in C:\wamp\bin\php\Zend_Framework\library\Zend\Loader.php on
line 146
As if it has no idea what adapter I'm speaking of.
I'm using this in my boot strap
protected function _initDb()
{
$this->bootstrap('config');
$config = $this->getResource('config');
$db = Zend_Db::factory('Php_Firebird', array(
'host' => $config->Database->Server,
'username' => $config->Database->Username,
'password' => $config->Database->Password,
'dbname' => $config->Database->DBName
));
return $db;
}
I'm assuming this has something to do with the fact this is ZendX stuff not Zend\db stuff but I cannot find an example of it. Or from the factory function using a ZendX adapter. I tried to use 'Php_Interbase' but that was not found either (and I dont see it in the folders anyway). And I tried Pdo_Firebird as well which of course didnt work.
Has someone done this that can point me to what I'm doing wrong?
Thanks
You just need to add adapterNamespace to the configuration array you are passing to the factory. See the 3rd example here, also remove 'PHP_' from the adapter name, so your call to the factory should look like this:-
$db = Zend_Db::factory('Firebird', array(
'host' => $config->Database->Server,
'username' => $config->Database->Username,
'password' => $config->Database->Password,
'dbname' => $config->Database->DBName,
'adapterNamespace' => 'ZendX_Db_Adapter'
));
Try something like
$db = new ZendX_Db_Adapter_Firebird(array(
//config part
));

Categories