How to properly initialize database connection in Phalcon - php

at the moment, I initialize database in following way:
$di->set('db', function() use ($config){
return new \Phalcon\Db\Adapter\Pdo\Mysql(
array(
"host" => $config->database->host,
"username" => $config->database->username,
"password" => $config->database->password,
"dbname" => $config->database->name
)
);
});
but when mysql credentials are wrong, or database doesn't exist, Phalcon returns blank page without any error message. Such situations are real headache, because small error in login/password/host causes almost untraceable error.
I think that Pdo constructor stops PHP code execution in this case.
So how do you initialize database connection in Phalcon when you want website to tell you about problem with database?

I ended with following code:
$di->set('db', function() use ($config){
try {
$db = new \Phalcon\Db\Adapter\Pdo\Mysql(
array(
"host" => $config->database->host,
"username" => $config->database->username,
"password" => $config->database->password,
"dbname" => $config->database->name
)
);
} catch (Exception $e) {
die("<b>Error when initializing database connection:</b> " . $e->getMessage());
}
return $db;
});
Please tell me if there is a better way.

I use this configuration:
$di->set('db', function () use ($config) {
$connection = new \Phalcon\Db\Adapter\Pdo\Mysql(array(
"host" => $config->database->host,
"username" => $config->database->username,
"password" => $config->database->password,
"dbname" => $config->database->dbname,
"options" => array(
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'"
)
));
if (APPLICATION_ENV == 'development') {
$eventsManager = new Phalcon\Events\Manager();
$logger = new Phalcon\Logger\Adapter\File($config->application->logsDir . "sql_debug.log");
//Listen all the database events
$eventsManager->attach('db', function ($event, $connection) use ($logger) {
if ($event->getType() == 'beforeQuery') {
$logger->log($connection->getSQLStatement(), Logger::INFO);
}
});
//Assign the eventsManager to the db adapter instance
$connection->setEventsManager($eventsManager);
}
return $connection;
}, true);
there is one more option for utf8 and if application enviroment is development, it logs all the sql calls to sql_debug.log. You can see, that I'm using $config, its defined like this:
switch (APPLICATION_ENV) {
case 'development':
$config = new Phalcon\Config\Adapter\Ini(__DIR__ . '/../app/config/config_dev.ini');
break;
case 'testing':
$config = new Phalcon\Config\Adapter\Ini(__DIR__ . '/../app/config/config_test.ini');
break;
case 'production':
$config = new Phalcon\Config\Adapter\Ini(__DIR__ . '/../app/config/config_production.ini');
break;
}
and in config file you would find something like this:
[database]
adapter = Mysql
host = localhost
username = root
password =
dbname = db_name

You can make it more general. Sou you can catch all the errors that may occur and display them nicely.
I'm using below bootstrap file (config) for developement as described here.
<?php
error_reporting(-1);
$debug = new Phalcon\Debug();
$debug->listen();
/** Read the configuration */
$config = include __DIR__ . '/../config/config.php';
/** Read auto-loader */
include __DIR__ . "/../app/config/loader.php";
/** Read services */
include __DIR__ . "/../app/config/mvc/services.dev.php";
/** Handle the request */
$application = new \Phalcon\Mvc\Application();
$application->setDI($di);
if (!empty($_SERVER['REQUEST_URI'])) {
$uriParts = explode('?', $_SERVER['REQUEST_URI']);
$uri = $uriParts[0];
} else {
$uri = '/';
}
echo $application->handle($uri)->getContent();
Which concludes that interesting part is here:
$debug = new Phalcon\Debug();
$debug->listen();

Does setting error reporting in your phalcon.ini help?
extension=phalcon.so
error_reporting = E_ALL | E_STRICT
display_errors = On

Related

how to set dynamic database values through classes and objects in php5

This is my code
<?php
class Connection
{
function __construct()
{
if(isset($_SERVER['SERVER_NAME']))
{
switch($_SERVER['SERVER_NAME'])
{
case 'www.hashstar.com':
$this->default = $this->dev;
break;
case 'www.hashstar.in':
$this->default = $this->prod;
break;
}
}
else
{
$this->default = $this->dev;
}
}
public $dev = array(
'host' => 'localhost',
'login' => 'root',
'password' => '',
'database' => 'dbname',
);
public $prod = array(
'host' => 'localhost',
'login' => 'db_admin',
'password' => 'Admin#.2017',
'database' => 'db_main',
);
public function establish_connection()
{
$connection = new mysqli($this->host, $this->user, $this->pass, $this->db);
if($connection == TRUE)
{
return $connection;
}
else
{
die("Could Not Establish Connection! ".$connection->error);
}
}
}
?>
The problem with this code is that i have declared here varaibles 1st for offline and 2nd for online as i am using git i have to again and again change the codes before pushing to master branch. I even tried to use the .gitignore feature but it isn't working as well but still i wan to set the variables dynamically according to the server host.
I have tried using the switch case thing but its giving an syntactical error while compiling. Can anyone help mw with this code.
Any helps appreciated.
Set your database credentials in a new file that you will then add to .gitignore like so :
$dbConfig = array(
"host" => "localhost",
...
)
then simply access to your $dbConfig in your Connection class

Unable to get User Credential grant type working

I have a Laravel 4.2 app that I have successfully implemented Authorization Code using oauth2-server-php. However, I can't seem to get User Credential grants working.
Here's my code setting up the oauth server:
App::singleton(
'oauth2',
function () {
$host = Config::get('database.connections.mongodb.host');
$hosts = is_array($host) ? $host : [$host];
$dbName = Config::get('database.connections.mongodb.database');
$dbOptions =
empty( Config::get('database.connections.mongodb.options') ) ? [] : Config::get(
'database.connections.mongodb.options'
);
$mongo = new MongoClient('mongodb://' . implode(',', $hosts) . '/' . $dbName, $dbOptions);
$storage = new OAuth2\Storage\Mongo($mongo->{$dbName});
$server = new OAuth2\Server(
$storage, [
'always_issue_new_refresh_token' => true,
'refresh_token_lifetime' => 2419200,
]
);
$userStorage = new \Medusa\Oauth\Storage\MedusaUserCredentials();
$server->addStorage($userStorage, 'users');
$userCredentialGrant = new Oauth2\GrantType\UserCredentials($userStorage);
$server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage));
$server->addGrantType(new OAuth2\GrantType\ClientCredentials($storage));
$server->addGrantType($userCredentialGrant);
$server->addGrantType(new OAuth2\GrantType\RefreshToken($storage));
return $server;
}
);
MedusaUserCredentials has the following code:
namespace Medusa\Oauth\Storage;
use OAuth2\Storage\UserCredentialsInterface;
class MedusaUserCredentials implements UserCredentialsInterface
{
public function checkUserCredentials($username, $password)
{
return Auth::attempt(['email_address' => strtolower($username), 'password' => $password, 'active' => 1]);
}
public function getUserDetails($username)
{
return ['user_id' => $username];
}
}
When I post to the web server to the token route using a raw payload of
grant_type=password&username=<USERNAME>&password=<PASSWORD>
I just get the login page. The token route looks like this
Route::post(
'oauth/token',
function () {
$bridgedRequest = OAuth2\HttpFoundationBridge\Request::createFromRequest(Request::instance());
$bridgedResponse = new OAuth2\HttpFoundationBridge\Response();
$bridgedResponse = App::make('oauth2')->handleTokenRequest($bridgedRequest, $bridgedResponse);
print_r($bridgedResponse); die();
return $bridgedResponse;
}
);
What am I missing?
Thanks!
I found the issue -- I had a namespace issue that I had to resolve. For some reason, my app returned a 200 OK response and the normal login page, so I didn't think to check the logs.
I know, bad dev, no cookie!

How can i send dynamic data in bootstrap file for Email in zend framework

I am sending email to user while registration. For that i am using Zend's default function.
For that i added code in my Bootstrap file.
protected function _initMail()
{
try {
$config = array(
'auth' => 'login',
'username' => 'username#gmail.com',
'password' => 'password',
'ssl' => 'tls',
'port' => 587
);
$mailTransport = new Zend_Mail_Transport_Smtp('smtp.gmail.com', $config);
Zend_Mail::setDefaultTransport($mailTransport);
} catch (Zend_Exception $e){
}
}
Now my need is username,password and port i want to make this field dynamic. I want to fetch this record from the database. Can anyone please tell me how can i solve that problem. Any help will be appreciated.
I would say that you do not put these into the database. A better way would be to put them into a config file and then set them up from there. Doing a database call EVERY SINGLE time your application is called is not really optimal.
The way you should be doing it is:
protected function _initMail()
{
try {
$config = Zend_Controller_Front::getInstance()->getParam('bootstrap');
$config = $config->getOption("mail");
$mailTransport = new Zend_Mail_Transport_Smtp('smtp.gmail.com', $config);
Zend_Mail::setDefaultTransport($mailTransport);
} catch (Zend_Exception $e){
}
}
That is assuming that your application.ini has this:
mail.auth="login"
mail.username="username#gmail.com"
mail.password="password"
mail.ssl="tls"
mail.port=587
However if you decide you want to do this, and have set up your database in the application.ini file (assuming you use ini files for config) something like this:
resources.db.adapter = "PDO_MYSQL"
resources.db.params.host = "your.database.host"
resources.db.params.dbname = "database_name"
resources.db.params.username = "username"
resources.db.params.password = "password"
resources.db.isDefaultTableAdapter = true
You can then do:
protected function _initMail()
{
$resource = $bootstrap->getPluginResource('db');
$db = $resource->getDbAdapter();
$select=$db->select()->from("emailSetup");
$credentials=$db->fetchOne($select);
[..email part here..]
}
P.S. I have not tested the select, but you should get the gist of it.

Zend LDAP authentication - How to setIdentity and getIdentity

I am using adldap library to authenticate users against Active Directory. Below is the piece of code I use to authenticate
$username = $_POST['username'];
$password = $_POST['password'];
require_once '/adlap/adLDAP.php';
try {
$adldap = new adLDAP();
}
catch (adLDAPException $e) {
echo $e;
exit();
}
$authUser = $adldap->user()->authenticate($username, $password);
How should I setIdentity for the user?
In Login system where we store username and password we can setIdentity as mentioned below
$adapter = $this->_getAuthAdapter();
$adapter->setIdentity($values['username']);
$adapter->setCredential($values['password']);
protected function _getAuthAdapter() {
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter->setTableName('users')
->setIdentityColumn('username')
->setCredentialColumn('password')
->setCredentialTreatment('SHA1(CONCAT(?,salt))');
return $authAdapter;
}
I am not storing password in Database and checking it directly against Active Directory. So I couldn't use the above solution.
How shall I setIdentity of users so that I can check if user hasIdentity() like this
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()){
}
I referred the following Stackoverflow question
Get display name for Zend LDAP Authentication.
However I am not sure how we shall "get('LDAP_host')" Zend Registry and how should we set it before. Below is the line of code I'm confused with
'host' => Zend_Registry::get('LDAP_host'),
Can someone please help me?
Zend_Registry::get('LDAP_host') simply returnes the hostname of your LDAP-Server. Somewhere before that line of code you will find a line similar to Zend_Registry::set('LDAP_host', 'ldap.example.com') which sets ldap.example.com as LDAP-server.
getAuthAdapter() in your case returns an instance of Zend_Auth_Adapter_DbTable but you want an instance of Zend_Auth_Adapter_Ldap. So you will have to either call a different method/function getLdapAuthAdapter() or rewrite the current method.
public function getLdapAuthAdapter() {
return new Zend_Auth_Adapter_Ldap(array(
'host' => 'ldap.example.com',
'accountDomainName' => 'example.com',
'accountDomainNameShort' => 'EXAMPLE',
'accountCanonicalForm' => 3,
'username' => "CN=user1,DC=example,DC=com",
'password' => 'pass1',
'baseDn' => "DC=example,DC=com",
'bindRequiresDn' => true,
));
}
$adapter = $this->getLdapAuthAdapter();
$adapter->setIdentity($values['username']);
$adapter->setCredential($values['password']);
$result = $adapter->authenticate();
Hope that somehow helps.

Silex sessions not saving data?

After finding this question I got my Silex sessions to at least get an ID assigned, but I'm not seeing the session data get saved across different page views:
require(__DIR__.'/vendor/autoload.php'); // Composer autoload
$app = new Silex\Application();
$app['debug'] = true;
$app['db'] = $app->share(function() { // Database connector as a service
return new PDO('mysql:host=localhost;dbname=myawesome_db', 'user', 'paswd');
});
$app['session.db_options'] = array(
'db_table' => 'php_sessions',
'db_id_col' => 'session_id',
'db_data_col' => 'session_value',
'db_time_col' => 'session_time',
);
$app['session.storage.pdohandler'] = $app->share(function () use ($app) {
return new Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler(
$app['db'],
$app['session.db_options'],
$app['session.storage.options']
);
});
$app['session.storage'] = $app->share(function() use ($app) {
return new Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage(
$app['session.storage.options'],
$app['session.storage.pdohandler']
);
});
$app->register(new Silex\Provider\SessionServiceProvider()); // Start session management
$app['session']->start();
$app->get('/session-set', function() use ($app) {
$app['session']->set('foobar', 'test');
$app['session']->save();
$out = "User session is: ".$app['session']->getId()."<br />\n";
$out .= "Session variable is: ".var_export($app['session']->get('foobar'), true)."<br />\n";
return $out;
});
$app->get('/session-get', function() use ($app) {
$out = "User session is: ".$app['session']->getId()."<br />\n";
$out .= "Session variable is: ".var_export($app['session']->get('foobar'), true)."<br />\n";
return $out;
});
$app->run(); // Off into the sunset
The /session-set page shows a value for the foobar session variable, but the /session-get page does not. Anyone able to help me figure out why?
My solution turned out to be that the PDO database connection was not set up properly (one of the column names was wrong). However, by default, the PDO MySQL connection doesn't throw Exceptions when it errors out, it just sets the ErrorInfo() detail. Once I turned on Exception throwing for my PDO connection, I found the error and fixed it. I also submitted a patch to Symfony to ensure that the session PDO object has Exception-throwing enabled, to avoid others hitting this problem.

Categories