Setting up a database for Yii 2 - yii2

I need to install an app written in Yii 2 on my local computer. I installed composer and initiated the app with:
php /path/to/yii-application/init
Now I need to "create a new database and adjust the components['db'] configuration in common/config/main-local.php accordingly."
I have no clue how to do that.

1) Create database on your server.
2) Open common/config/main-local.php
Edit components to:
'components' => [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=DATABASE_NAME',
'username' => 'DATABASE_USER',
'password' => 'DATABASE_PASSWORD',
'charset' => 'utf8',
],
If using MAMP with mac then edit dsn line to :
'dsn' => 'mysql:unix_socket=/Applications/MAMP/tmp/mysql/mysql.sock;dbname=DATABASE_NAME'

Related

Yii2 Read Write splitting couldn't connect slave server in master slave configuration

Have done Master Slave configuration as per official Yii2 documentation. Below is actual configuration look like,
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=1.1.1.1;dbname=master_db',
'username' => 'user',
'password' => 'password',
'charset' => 'utf8',
'enableSchemaCache' => true,
'schemaCacheDuration' => 10,
'schemaCache' => 'cache',
'slaveConfig' => [
'username' => 'slave_user',
'password' => 'slave_password',
'charset' => 'utf8',
'attributes' => [
// use a smaller connection timeout
PDO::ATTR_TIMEOUT => 10,
],
'enableSchemaCache' => true,
'schemaCacheDuration' => 10,
'schemaCache' => 'cache',
],
'slaves' => [
['dsn' => 'mysql:host=2.2.2.2;dbname=slave_db']
],
],
It always connect master database even if slave server is up and reachable.
Surprisingly replacing current master config with slave one works, moreover if try to connect slave database from command line it get connected in a moment but unable to achieve same with above configuration.
Wondering if there is any parameters missing in configuration or any other way to get things working like ideal read write splitting?
issue was resolved by adding connection class in the slaveConfig,
'class' => 'yii\db\Connection'

Yii2 Failing to instantiate component or class "db"

I use a Yii2 console application to run migrations. It's a very basic app, that goes like this (yii.php in the / folder of the project):
<?php
require __DIR__ . '/vendor/autoload.php';
require __DIR__ . '/vendor/yiisoft/yii2/Yii.php';
$config = require __DIR__ . '/config/console.php';
(new yii\console\Application($config))->run();
?>
So when i run
php yii.php
Everything's fine, but when i run
php yii.php migrate/create create_user_table
I am getting an error message:
Error: Failed to instantiate component or class "db".
My Yii is v2.0.15.1
UPD 19:32 30/12/2018
When I add a db config to a config/console.php like this:
return [
'id' => 'school-console',
'basePath' => dirname(__DIR__),
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=school',
'username' => 'root',
'password' => 'Taras1love',
'charset' => 'utf8',
]
];
I get this:
Error: Setting read-only property: yii\console\Application::db
You are missing the database component configurations for the console application you need to add the following inside the config/console.php file. As you are usign the basic-app for Yii2 you must have a db.php file with the database configurations, you need to include it like below
//this goes on the top of your `console.php` file
$db = require __DIR__ . '/db.php',
return [
'id' => 'myapp-console',
'basePath' => dirname(__DIR__)
//add the db component
'components' => [
'db' => $db,
]
];
Your db.php should be like below inside the config folder, change the values for the username, password and dbname.
<?php
return [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=YOUR_DB_NAME',
'username' => 'DB_USER',
'password' => 'DB_PASS',
'charset' => 'utf8',
];
or you can assign it inside the config/console.php if you dont want to create a separate file
return [
'id' => 'myapp-console',
'basePath' => dirname(__DIR__)
//add the db component
'components' => [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=YOUR_DB_NAME',
'username' => 'DB_USER',
'password' => 'DB_PASS',
'charset' => 'utf8',
]
]
];
I found that I got this problem if I ran yii directly from vendor/bin.
If I went to the console directory and ran it from there using ./yii, I did not get this error and was able to create the migration.
In other words:
cd <project-root>/vendor/bin
yii migrate/create xxx
did not work
But:
cd <project-root>/console
./yii migrate/create xxx
did work
this happened to me because I accidentally renamed my migration and it was not matching the file name

How can I use an existing database with the advanced template of Yii2?

I installed the yii2 advanced template, and I'm now at migration point where I should create a new database and migrate the app to it.
but I already have a database full of data and I want to use it with yii2 without modifying anything
Open the file
common/config/main.php
and add the parameters for your database connection
<?php
return [
'components' => [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => '',
'username' => '',
'password' => '',
'charset' => 'utf8',
],
],
];

lavaral 5 ERROR{ (SQLSTATE[HY000] [1045] Access denied for user 'root'#'localhost' (using password: YES)}

'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'database' => storage_path('database.sqlite'),
'prefix' => '',
],
**JUST CHANGED THE CODE FOR LOCALHOST AND CHANNGED THE NAME TO ROOT AND SET THE PASSWORD OF PHPMYADMIN . **
**WHEN WRITTING THE COMMAND IN XAMPP SHELL ((Php artisan migrate:install)) **
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'laravel'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', 'password'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'password'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'password'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
],
],
/*
|--------------------------------------------------------------------------
| Migration Repository Table
|--------------------------------------------------------------------------
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk haven't actually been run in the database.
|
*/
'migrations' => 'migrations',
/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer set of commands than a typical key-value systems
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => [
'cluster' => false,
'default' => [
'host' => '127.0.0.1',
'port' => 6379,
'database' => 0,
],
],
it is showing error SQLSTATE[HY000] [1045] Access denied for user 'root'#'localhost' (using password: YES)
By default laravel assumes that you will want to have different configurations for different environments. E.g. in a testing environment, you might wish to have a different username and password and in a production environment different. Since laravel has so many configuration files, it quickly becomes a nightmare to manage all those. Hence laravel makes use of PHP's environment variables.
See the docs here.
What is basically says is that if you wish to use the "environment" variables, which laravel uses by default, you have to place all your configurations in the env() method as already mentioned.
If you do not wish to do this, e.g. for simple projects, simply remove the env from your code, like this.
'mysql' => [
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'laravel',
'username' => 'root',
'password' => 'password',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
Note that you can mix and match. i.e you can have some of the variables in env and some stand-alone.
So why use env at all?
Lets say your application has 100 testers all placed in different locations. In laravel you have to code approximately 8-10 configuration files. Also you need to version-control those files. So you have two problems at hand:
You do not wish to send all 100 users the same credentials. Also they might use different database, cache server, etc which means that they will have different configurations. So every user has to maintain those 8-10 configuration files by hand.
You do not wish to send these configuration files to version control. Because if you do, whole world will know your API secrets and possibly will take advantage of that (just like password). Also if you look at laravel conf files, you will notice that there are other information such as timezone, debug property, etc that are also in conf files, and you do want to version-control them. So how do you version-control such configuration files and still hide your sensitive information.
The answer is env variables. Laravel uses dotenv whose documentation can be found here. Basically these are variables that live in one file called .env in a key-value pair. E.g.
Sample contents of .env file
APP_DEBUG=false
APP_KEY=ABCDEFGH
...
Once you define your .env file as this, you can get the value using the key as such env('APP_DEBUG').
So this solves the above mentioned problem in following ways:
you keep the .env file to yourself. And you also declare another file called .env.example which is an exact replica of original file except the fact that it contains sample values, not your sensitive values. Then you pass this new example file to everyone. They will replace the sample data with their own sensitive information.
Since you are version-controlling the example file, you can version control all your conf files because they don't contain the secret. The secret is in .env files. All those conf files contain is values like these env('APP_KEY') and the actual value is replaced at run time using your .env file.
Make sure you have to set up right server credentials into .env file on your Laravel project:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=myapp_db
DB_USERNAME=root
DB_PASSWORD=pass
Try to clean up artisan cache and restart the artisan,
php artisan config:clear
restart php artisan

How to replace environment-specific config, not cascade

I want to have a local development environment configuration for my database.php. I've created a new config director in my app and copied the database.php file into it. I'm using MongoDB and on production, I'm using a replica set with multiple servers, but locally, I'm just running a single server, so my connection info for production has more options:
Production:
...
'connections' => array(
'mongodb' => array(
'driver' => 'mongodb',
'host' => array('mongoDBA', 'mongoDBB'),
'port' => 27017,
'username' => 'myUserName',
'password' => 'myPassword',
'database' => 'theDatabase',
'options' => array('replicaSet' => 'myReplicaSet')
)
),
Local:
...
'connections' => array(
'mongodb' => array(
'driver' => 'mongodb',
'host' => 'localhost',
'port' => 27017,
'database' => 'theDatabase'
)
),
The problem is, when my local environment config loads, it merges the "connections" array. I want a way to completely replace the "mongodb" connection, so it's either one or the other, not both.
How can I accomplish this?
Create different set of configuration files:
app/config/local/database.php
app/config/production/database.php
And delete the file (or what you don't want of it):
app/config/database.php
And the you have to set your environment as
local
development
EDIT
This is how I do set my environment flawlessly, so I don't have to deal with hostnames and still don't get my local environment conflict with staging and production.
Create a .environment file in the root of your application and define your environment and add your sensitive information to it:
<?php
return array(
'APPLICATION_ENV' => 'development', /// this is where you will set your environment
'DB_HOST' => 'localhost',
'DB_DATABASE_NAME' => 'laraveldatabase',
'DB_DATABASE_USER' => 'laraveluser',
'DB_DATABASE_PASSWORD' => '!Bassw0rT',
);
Add it to your .gitignore file, so you don't risk having your passwords sent to Github or any other of your servers.
Right before $app->detectEnvironment, in the file bootstrap/start.php, load your .environment file to PHP environment:
foreach(require __DIR__.'/../.environment' as $key => $value)
{
putenv(sprintf('%s=%s', $key, $value));
}
And then you just have to use it:
$env = $app->detectEnvironment(function () {
return getenv('APPLICATION_ENV'); // your environment name is in that file!
});
And it will work everywhere, so you don't need to have separate dirs for development and production anymore:
<?php
return array(
'connections' => array(
'postgresql' => array(
'driver' => 'pgsql',
'host' => getenv('DB_HOST'),
'database' => getenv('DB_DATABASE_NAME'),
'username' => getenv('DB_DATABASE_USER'),
'password' => getenv('DB_DATABASE_PASSWORD'),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
),
),
);
Note that I don't set a fallback:
return getenv('APPLICATION_ENV') ?: 'local';
Because, if I don't set the file, I want it to fail on every server I deploy my app to.