I am trying to learn Laravel 5.4. After I publish the command php artisan make:auth and publish the command php artisan migrate the following errors get displayed and some database tables do not get greated:
[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key
was too long; max key length is 767 bytes (SQL: alter table users
add unique users_email_unique(email)) [PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key
was too long; max key length is 767 bytes
Regarding the fact that I need to use some columns as a container of characters having Persian Script Font (some other columns contain English, Spanish ... characters), I created the MySQL database with utf8_general_ci and I suppose that the errors are initiated because of the database's encoding. Would you please tell me what character encoding I shall use to build the database with to be able to leverage Laravel's Auth capabilities? Thank you very much in advance.
Let's see SHOW CREATE TABLE so we can see the definition of email.
Meanwhile, I will guess that it includes something like
email VARCHAR(255) CHARACTER SET utf8mb4,
INDEX(email)
Do one of these (each has its drawbacks):
255 -> 191 (but make sure you don't currently have longer addresses)
utf8mb4 -> utf8 (thereby disallowing Emoji and some Chinese characters)
INDEX(email(20)) (If it is UNIQUE or PRIMARY KEY, do not pick this option)
It is possible to reconfigure (if after 5.6.3) the server and table to allow bigger indexes; this is not the 'default' until 5.7.7.
Laravel 5.4 has a documented issue on this error.
For others who run into this problem this is also a good fix:
open your app\Provider\AppServiceProvider.php
change it to:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
Schema::defaultStringLength(191); //
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
}
run migration again
Related
from laravel docs
Application Key The next thing you should do after installing Laravel
is set your application key to a random string. If you installed
Laravel via Composer or the Laravel installer, this key has already
been set for you by the php artisan key:generate command.
Typically, this string should be 32 characters long. The key can be
set in the .env environment file. If you have not renamed the
.env.example file to .env, you should do that now. If the application
key is not set, your user sessions and other encrypted data will not
be secure!
What I know about application key is: If the application key is not set, generally I do get an exception.
How do this random string help to secure the session?
What are the other uses of this application key?
If I use the same application key everywhere (like staging, production etc..) does it make the application less secure?
what are some best practices for this key
As we can see its used in EncryptionServiceProvider:
public function register()
{
$this->app->singleton('encrypter', function ($app) {
$config = $app->make('config')->get('app');
// If the key starts with "base64:", we will need to decode the key before handing
// it off to the encrypter. Keys may be base-64 encoded for presentation and we
// want to make sure to convert them back to the raw bytes before encrypting.
if (Str::startsWith($key = $this->key($config), 'base64:')) {
$key = base64_decode(substr($key, 7));
}
return new Encrypter($key, $config['cipher']);
});
}
So every component that uses encryption: session, encryption (user scope), csrf token benefit from the app_key.
Rest of the questions can be answered by "how encryption" (AES) works, just open up Encrypter.php, and confirm that Laravel uses AES under the hood and encodes the result to base64.
Further more we can see how its all done by using tinker:
➜ laravel git:(staging) ✗ art tinker
Psy Shell v0.8.17 (PHP 7.1.14 — cli) by Justin Hileman
>>> encrypt('Hello World!')
=> "eyJpdiI6ImgzK08zSDQyMUE1T1NMVThERjQzdEE9PSIsInZhbHVlIjoiYzlZTk1td0JJZGtrS2luMlo0QzdGcVpKdTEzTWsxeFB6ME5pT1NmaGlQaz0iLCJtYWMiOiI3YTAzY2IxZjBiM2IyNDZiYzljZGJjNTczYzA3MGRjN2U3ZmFkMTVmMWRhMjcwMTRlODk5YTg5ZmM2YjBjMGNlIn0="
Note: I used this key: base64:Qc25VgXJ8CEkp790nqF+eEocRk1o7Yp0lM1jWPUuocQ= to encrypt Hello World!
After decoding the result we get (you can try decode your own cookie with session):
{"iv":"h3+O3H421A5OSLU8DF43tA==","value":"c9YNMmwBIdkkKin2Z4C7FqZJu13Mk1xPz0NiOSfhiPk=","mac":"7a03cb1f0b3b246bc9cdbc573c070dc7e7fad15f1da27014e899a89fc6b0c0ce"}
to understand above json (iv, value, mac) you need to understand AES:
https://en.wikipedia.org/wiki/Advanced_Encryption_Standard
Best practices for application key
do store it in .env file only
do not store it in app.php, in fact in any git tracked file
do not change it unless you really want to
invalidate sessions/cookies (user logout)
invalidate password reset tokens
invalidate signed urls
Obvious Note: Changing application key has no effect on hashed passwords since hashing algorithms do not require encryption keys.
Firstly i was getting an error in
php artisan migrate
as
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
and Then i found a post on laracasts to fix this as
use Illuminate\Support\Facades\Schema;
public function boot()
{
Schema::defaultStringLength(191);
}
After adding this, when i run
php artisan optimize
then i am presented with new error as below
Call to undefined method Illuminate\Database\Schema\MySqlBuilder::defaultStringLength()
Please assist in getting rid of all these errors.
defaultStringLength is introduced in Laravel v5.4. Reference.
You can update the Laravel version
OR
You specify the length as $table->string('coumname', 255); You cannot specify more than 255. If you leave the length parameter it will assign 255 by default
This is because Laravel 5.4 uses the utf8mb4 character set by default, which includes support for storing “emojis” in the database. You can choose any one from these 2 solutions:
1) Change
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
to
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
2) Edit AppServiceProvider located at App\Providers\AppServiceProvider.php and add the following line to the boot() method and load the Schema facade:
use Illuminate\Support\Facades\Schema;
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
Schema::defaultStringLength(191);
}
What that will do is actually change the default maximum field length in the database and actually shorten your maximum string length from 255 to maximum of 191 characters (utf8 uses 3 bytes per character while utf8mb4 uses 4 bytes per character your field can now hold 25% less characters 255 * 75% = 191.25). So if you don’t set the string field by hand in the migration the new default will be 191.
Find AppServiceProvider in Laravel Project
1.First Add Facade
use Illuminate\Support\Facades\Schema;
2.Add Below lines in boot function
function boot() {
Schema::defaultStringLength(191);
}
Add use Illuminate\Support\Facades\Schema; to your AppServiceProvider.php file in App/Providers folder.
Add Schema::defaultStringLength(191); to the boot function.
If Laravel < 5.4
1. Find AppServiceProvider in Laravel Project
2. Comment line or remove Schema::defaultStringLength(191) in boot method
I would like to create a copy of the structure only of an existing database without it data to a new database (same server).
I am using PHP 5.2.14
I tried:
CREATE DATABASE base3 WITH TEMPLATE base2 OWNER postgres;
And got this error:
ERROR: source database "base2" is being accessed by other users
********** Error **********
ERROR: source database "base2" is being accessed by other users
SQL state: 55006
I tried adding this code:
SELECT pg_terminate_backend(pg_stat_activity.procpid) FROM pg_stat_activity WHERE pg_stat_activity.datname = 'base2' AND procpid <> pg_backend_pid();
and get this error:
ERROR: function pg_terminate_backend(integer) does not exist
LINE 1: SELECT pg_terminate_backend(pg_stat_activity.procpid) FROM p...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
********** Error **********
ERROR: function pg_terminate_backend(integer) does not exist
SQL state: 42883
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Character: 8
Thanks if advance for your help.
In PostgreSQL 9.2 and above you should use pg_terminate_backend with integer argument and use pid field. Example bellow:
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'base2' AND pid <> pg_backend_pid();
Server Signaling Functions:
pg_cancel_backend and pg_terminate_backend send signals (SIGINT or SIGTERM respectively) to backend processes identified by process ID. The process ID of an active backend can be found from the pid column of the pg_stat_activity view, or by listing the postgres processes on the server (using ps on Unix or the Task Manager on Windows). The role of an active backend can be found from the usename column of the pg_stat_activity view.
pg_stat_activity was made available in version 8.4 and ownward.
Older version user can use these functions
as listed on documentation page
https://www.postgresql.org/docs/8.1/static/functions-admin.html
I'm trying to use doctrine2 migration and schema update with symfony2's console. All my entities are being generated with no problems via:
php app/console doctrine:generate:entities myProject
Also, I am able to create my database and build my schema from scratch with no problems given the following commands:
php app/console doctrine:database:create
php app/console doctrine:schema:create
Whenever I modify, remove, or add in another entity, I always regenerate my entities with:
php app/console doctrine:generate:entities myProject
The problem however, is whenever I want to update my schema I always get the following error:
[Doctrine\DBAL\DBALException]
An exception occurred while executing 'CREATE INDEX IDX_F7129A80A76ED395 ON
user_user (user_id)':
SQLSTATE[42000]: Syntax error or access violation: 1061 Duplicate key name
'IDX_F7129A80A76ED395'
[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1061 Duplicate key name
'IDX_F7129A80A76ED395'
I have tried doing:
php app/console doctrine:schema:update --force
or
php app/console doctrine:migrations:diff
php app/console doctrine:migrations:migrate
But I always get the same error. What am I doing wrong? Is there any way for me to update my database without having to destroy and build a whole new one every time? I have over 25 entities which consist of large files with many associative mappings (OneToOne, OneToMany, ManyToMany,.. etc) which seems to be causing problems. Any help would be great! Thanks!
On a side note I have a feeling that this piece of code might be causing the problem:
/**
* #ORM\ ManyToMany(targetEntity="User", inversedBy="myFriends")
*/
protected $friendsWithMe;
/**
* #ORM\ ManyToMany(targetEntity="User", inversedBy="friendsWithMe")
* #ORM\ JoinTable(name="friends",
* joinColumns={#ORM\ JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\ JoinColumn(name="friend_user_id", referencedColumnName="id")}
* )
**/
protected $myFriends;
In my user entity, I wanted to build a self-referencing many to many relationship. This is how I'm building out a friends list. Maybe there is something wrong with my logic, but I took this directly off from the doctrine2 documentation on associative mapping.
Not sure it is the cause of the Exception, but there is an error in your ORM mapping. $myFriends is the owning side, $friendsWithMe is the inverse side, so inversedBy attribute should be only present on $friendsWithMe.
Try to rewrite $myFriendswith mappedBy attribute :
/**
* #ORM\ ManyToMany(targetEntity="User", mappedBy="friendsWithMe")
* #ORM\ JoinTable(name="friends",
* joinColumns={#ORM\ JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\ JoinColumn(name="friend_user_id", referencedColumnName="id")}
* )
**/
protected $myFriends;
I wanted to make a tryout this weekend with Cassandra + PHP in my testing environment. So after a few hours of headache trying to install it, I finally succeeded and got it running.
However, I've tried out the different PHP wrappers for cassandra, and I have totally failed to connect with anyone. SimpleCassie which I want to use, gives the following error when I run the following code:
/*
* setting new column (and key if not exist)
* #return - (false) on failure
*/
$cassie->keyspace('MyApp')->cf('Users')->key('user1')->column('name')->set('Marcin');
$cassie->column('surname')->set('Rosinski');
Error:
cassandra_InvalidRequestException: in /var/www/cassie/SimpleCassie.php on line 7257
What Can I do to make it work?
Thanks!
"Invalid request could mean keyspace or column family does not exist, required parameters are missing, or a parameter is malformed. why contains an associated error message."
My qualified guess is that you have forgot to add a keyspace called 'MyApp', and inside that keyspace create a column family called 'Users'