I'm working on a rewrite of a project from the ground up and figured I would try to learn MVC along the way. In this case, I've chosen Phalcon and am still working through the fundamentals of converting the tutorials to my own project.
I have two "configuration" settings that I need to account for. First, I need to read a configuration file that has the database credentials (this works properly).
require_once('../fileconfig.php'); // Read config file
$init = new Phalcon\Config\Adapter\Php("../fileconfig.php"); //Convert it to array
But once I have that, how do I actually connect to the database and add it to $di-> (which, if I understand correctly, is effectively the global class? Ultimately, I want to pull the contents of "select * from config" into an array and use that for the application configuration. In this case, var_dump($dbh) returns "null"
//Connect to database
$di->set('db', function() use ($init) {
$dbh = new \Phalcon\Db\Adapter\Pdo\Mysql([
"host" => $init->database->host,
"username" => $init->database->username,
"password" => $init->database->password,
"dbname" => $init->database->dbname
]);
return $dbh;
});
var_dump($dbh); //returns null
If I remove the $di-> section, the array returns the data that I need, but it still doesn't help me figure out how to connect to the database and have it available globally for other functions in the models:
$dbh = new \Phalcon\Db\Adapter\Pdo\Mysql([
"host" => $init->database->host,
"username" => $init->database->username,
"password" => $init->database->password,
"dbname" => $init->database->dbname
]);
Returns:
object(Phalcon\Db\Adapter\Pdo\Mysql)[28]
protected '_descriptor' =>
array (size=4)
'host' => string 'localhost' (length=9)
'username' => string 'testuser' (length=8)
'password' => string 'testpass' (length=8)
'dbname' => string 'testdb' (length=6)
This question seems to be close to what I'm asking, but was more about error handling than the actual connection and I didn't see an answer to my question there.
To resolve your database you need to resolve your di. You could resolve it the file you declared it in with
$di->getShared('db')
But note, you don't want to do that. You want your files seperated with their responsibilities.
Inside of a class that inherits \Phalcon\Mvc\Controller you can use
$this->db->
Please refer to http://docs.phalconphp.com/en/latest/reference/di.html in order to see why to use a DI, and all the nuances of accessing it
It really helps to go through other phalcon projects and look at how everything works together. Please refer to the source here and look at how projects are set up:
https://github.com/phalcon/invo
https://github.com/phalcon/vokuro
https://github.com/phalcon/forum
These are ranked by complexity so start with invo first and then move on
Related
I suppose I am a noob with PHP so apologies if I sound dumb, but, I do have a troubling dilemma, I have spent the last six hours plus scouring Google for any hints and found none so here I am on the SO forum looking for some 'pointers' in the right direction.
I have an issue with returning 3DAA's from a function in a class to other parts of my code and no matter what I try I'm getting a null value back, according to the error log anyway, but when I run this code separately from the framework, in a single file using the same declarations it miraculously starts working and echos the specified part of the array to the screen wahey, but I don't know why it suddenly works nor why it won't work in the framework and supplies a null value.
I was wondering if anyone out there has experienced such weird errors with returning 3DAA's and if so, how they got around it. If you want to see the code ask and I'll post it.
<?php
class Core {
public function GetConfiguration() {
$configuration = array(
"cobalt" => array(
"name" => 'Cobalt',
"version" => '1.0.7',
"directory" => array(
"root" => 'application',
"modules" => 'application/modules',
"html" => 'application/html'
)
),
"application" => array(
"name" => 'Cardinal Technologies',
"version" => '1.0.2',
"server" => 'http://localhost',
"seo" => array(
"copyright" => 'Ida Boustead',
"description" => 'Welcome to Cardinal Technologies, here at Cardinal Technologies we pride ourselves in providing the best possible customer service whether you need a repair or upgrade for a computer, android phone or tablet, even alarms and CCTV',
"keywords" => 'computer repair,computer upgrade,computer upgrades,android phone repair,phone repair,android tablet repair,tablet repair,alarms,cctv,network installation,network install',
"robots" => 'index,follow'
)
)
);
return $configuration;
}
public function LoadModule($module) {
require_once 'application/modules/' . $module . '.class.php';
}
}
?>
Hope this helps.
I'm calling it like this.
require_once 'application/Core.class.php';
$core = new Core();
$configuration = $core->GetConfiguration();
and getting an array value like this.
$dir = $configuration['cobalt']['directory']['html'];
the prior is a snippet from a larger file but this is what relates to that function.
I get PHP Notice: Undefined variable: dir in the log which is what led me to believe the function was the problem.
If I echo $dir it echos application/html which is what it's supposed to, but it is not usable for anything other than echo which is pointless to me as I need that value to make other parts of the framework work.
Right it was me being a dumb dumb, I put the declarations in the wrong place, outside of the class and it did not like it.
I moved them to inside of each function that stalled the code and it fixed that issue. Thanks anyway.
I have the following setup with Laravel 4.2:
bootstrap/start.php (hostname correct, environment is local)
$env = $app->detectEnvironment(array(
'production' => array('produrl'),
'local' => array('MBP-Ivo.local', 'iMac-Ivo.local'),
));
.env.local.php (in project root, .env.php is exactly the same except mysql info)
<?php
return [
// Code variables
'mysqlUsername' => 'user',
'mysqlPassword' => 'password',
'mysqlDatabase' => 'database',
'paymentIdeal' => false,
'shipmentCountries' => [
'Nederland' => 'Nederland',
'Belgie' => 'Belgie'
]
];
config/app.php (I don't overwrite with app/config/local/app.php)
<?php
return array(
'paymentIdeal' => $_ENV['paymentIdeal'],
'shipmentCountries' => $_ENV['shipmentCountries']
);
There are some more variables, but the problem is with shipmentCountries.
Undefined index: shipmentCountries
All variables declared are working (eg paymentIdeal), but shipmentCountries gives an error. I think because it's an array? The name is exactly the same everywhere, including capital letters.
Does anyone know why I can't get this working?
BTW: I'm choosing this option to prevent users having to change their application configs. I want to use only one *.env file to configure all important stuff. And yes, I know these values could be saved to the database, but that's for later :)
/edit:
When I dump the $_ENV, I get the following:
Array
(
[mysqlUsername] => ***
[mysqlPassword] => ***
[mysqlDatabase] => ***
[paymentIdeal] =>
[shipmentCountries.Nederland] => Nederland
[shipmentCountries.Belgie] => Belgie
);
Somehow it "flattens" the array shipmentCountries. Anyone knows how and why?
You're right, the file get's converted in a flat array using the dot notation (with array_dot)
I believe the reason behind this, is that environment variables are just not supposed to be arrays as they are normally passed in when using a CLI.
So, what can you do about it?
Convert the array from dot to non-dot
In your app/start/global.php use this code to convert the array back to it's original format:
$array = array();
foreach ($_ENV as $key => $value) {
array_set($array, $key, $value);
}
$_ENV = $array;
Use another file and load it yourself
Also inside app/start/global.php (this would be .my.env.local.php)
$config = require base_path().'/.my.env.'.app()->env.'.php';
$_ENV = array_merge($_ENV, $config);
Sidenotes
I'd think again if you really don't want to use config files. It is possible to have your own config file and maybe you can even place it in the root of the project.
Also I'd change the array to a numeric one:
'shipmentCountries' => [
'Nederland',
'Belgie'
]
With the tip of lukasgeiter, I went searching again, and found this:
https://github.com/laravel/framework/issues/5291 and https://github.com/laravel/framework/pull/4623
It looks like Laravel doesn't support this option.
What I do now is save it as a JSON string, and decode it when neccesary.
Another way is to json_encode your associative array in the env.local.php, then in your config
json_decode($_ENV['shipmentCountries'],true);
Don't forget the boolean argument there to make it convert into arrays.
I have following database configuration in database.php file from my CakePHP app:
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'root',
'password' => '',
'database' => 'database',
'prefix' => '',
);
All is working fine, except of one queue shell script. The script is looping and waiting for commands to run (for example to update some reports). After a while 1-2 days database data is changing, but the script will still "see" the old data, and results of command is wrong. If I restart shell script, the results are OK... for few days.
I have to mention that I had "lost database connection" issue before in the script and I have solved it by runing every 10-15 min:
$user = $this->User->find('first');
Now I am affraid this is making the connection persistent somehow...
How can I reset the database connection ?
EDIT:
I was just refactoring the code to check if I can set $cacheQueries to false on the Model. But in few parts of the code I am using ConnectionManager directly, and only then I have "cache" problem. If I query database from Model->find results are ok. I need direct queries for performance reasons in few places...
$query = "SELECT COUNT(1) as result
FROM
......
";
$db = ConnectionManager::getDataSource('default');
$result = $db->query($query);
The property $cacheQueries which #burzum mentioned, seems not to be in use in any cake model method.
But I found another interesting fact in the source of the DboSource.
You need to use the second parameter of the DboSource::query() method to turn off the caching. Or the third if you want to provide additional parameters for the DboSource::fetchAll() method.
Eventhough this will fix your problem, you should write your queries with the Model::find() method that CakePHP offers.
You should only not use them if they are seriously impacting your performance.
func0der
Try to set these two model properties to false:
$cacheQuery http://api.cakephp.org/2.4/source-class-Model.html#265
$cacheSources http://api.cakephp.org/2.4/source-class-Model.html#499
I'm going to implement login functionality using zend framework 2.
My code as follows.
$dbAdapter = new DbAdapter(array(
'driver' => 'Mysqli',
'database' => 'db',
'username' => 'root',
'password' => 'password'
));
$authAdapter = new AuthAdapter($dbAdapter);
$authAdapter
->setTableName('admin_users')
->setIdentityColumn('user_name')
->setCredentialColumn('password')
;
$authAdapter
->setIdentity($username)
->setCredential($password)
;
$result = $authAdapter->authenticate();
It gives error message as follows.
The supplied parameters to DbTable failed to produce a valid sql statement, please check table and column names for validity.
I checked database configurations and column names. But they are correct. Can anyone give me a clue to check this out please.
Thanks.
There's no need to re-invent the wheel and struggle with this yourself. ZF2 has been created with modularity in mind so that plug in modules for this kind of thing can be written.
There are a few such modules available already at the ZF-Commons site. The one you are looking for is ZfcUser. Just follow the instructions to install and use it. There is even an excellent tutorial written by the author of the module that will take you through the whole process step by step. http://blog.evan.pro/getting-started-with-the-zf2-skeleton-and-zfcuser
There is also an excellent how-to page to tell you how to modify it for your own use.
I'm hosting a Yii app on shared-host with some my friend, and keep database in private MySQL server. As you knew, database info can be found so very easy in protected\config\main.php by another host owner (my friend and more):
'db'=>array(
'connectionString' => 'mysql:host=211.113.2.45;dbname=FamilyBook',
'emulatePrepare' => true,
'username' => root,
'password' => 'xcute445',
'charset' => 'utf8',
),
Is there any solution to conceal connection information as IP mySQL server, username, password?
May MySQL server provide RSA mechanism to protect database info?
Example, any people can see as below but cannot understand or use:
'db'=>array(
'connectionString' => '57bf064b2166366a5ea61109006b8d5c',
'emulatePrepare' => true,
'username' => '63a9f0ea7bb98050796b649e85481845',
'password' => 'e04ccf211208f8c97e4a36e584926e60',
'charset' => 'utf8',
), // value by MD5 function, example only
No, you cannot conceal the credentials from someone who has access to your source as long as you are using native MySql authentication. That's because your code needs to pass the credentials as cleartext¹ to the server, so it needs to be able to "decrypt" them before connecting. Someone who has access to your source can follow the same procedure and decrypt them as well.
You could secure your system by relying on some type of PAM authentication instead of user-supplied credentials, but Yii does not support such.
¹note: This is not actually true. The client passes a hash to the server, but it needs to have access to the original password in order to hash it. This means that for the purposes of this discussion it makes no difference (it would make a difference for someone who is listening on the network).
Using Yii 1.x I did it using below method.
create a class, DbConnection inside protected/components extending from CDbConnection
class DbConnection extends CDbConnection
{
public function createPdoInstance()
{
// Decrypt the password used in config file
// e.g.: $this->password = mydecrypt($this->password);
return parent::createPdoInstance();
}
}
Adjust the config file (protected/config/main.php)
'db' => array(
'class' => 'DbConnection', // Use above classname
'password' => 'encryptedpassword',
),