AES - which cipher is the safest one out there and what are the best practices for creating and storing the key I just started to learn cryptography. I've read a ton of articles but couldn't find a book or a course that is based on this subject (and also is not outdated). 

Therefore I have a few questions (some of them were asked before but there's no specific answer).

Also i must specify that all my questions are related to aes in PHP:

First question is what is the best way to create a completely random and unique key? So far I've made this little code that is (in my opinion) an overkill (and I guess it ads no extra security and randomness to the key since it is only 32 bytes in the end anyways) but still here it is:

$length = 32;
$hash = hash('sha512', microtime(true) . random_bytes(2) . chr(rand(0, 255)) . openssl_random_pseudo_bytes($length));
if((strlen($hash) / 2) &gt; $length){
    $x = rand($length / rand(1, $length), strlen($hash) - $length);
    $key = substr($hash, $x, $length);
} else{
    $key = substr($hash, 0, $length);
}


The cipher that I'm using is: aes-256-gcm. Is there a better cipher that I could use (a more secure one that has a longer key maybe)?

Also why does aes-256-gcm accept a longer than 32 bytes key but on decryption it just ignores anything above the first 32 bytes of that key?

Finally what is the best way to store the key for later usage (keeping in mind that I'm using php/mysql - I am aware of the fact that storing the key in the same database where you store the ciphertext/iv/tag is purely insane). 

PS: I do NOT use any of these lines in any project, those are just me trying to learn.
First question is what is the best way to create a completely random and unique key?


Simply generate an appropriately sized array of cryptographically random bytes from something like /dev/urandom, CryptGenRandom, or apparently openssl_random_pseudo_bytes.

The rest of your derivation process appears to serve no function; Even if it did, the entropy content of time and three random bytes is very low, so low that it can be guessed in practice.

So 

$length = 32;
$hash = hash('sha512', microtime(true) . random_bytes(2) . chr(rand(0, 255)) . openssl_random_pseudo_bytes($length));
if((strlen($hash) / 2) &gt; $length){
    $x = rand($length / rand(1, $length), strlen($hash) - $length);
    $key = substr($hash, $x, $length);
} else{
    $key = substr($hash, 0, $length);


Would become:

$length = 32;
$key = openssl_random_pseudo_bytes($length);


And that really is all that you need, assuming that openssl_random_pseudo_bytes provides cryptographically secure random bytes.


  The cipher that I'm using is: aes-256-gcm. Is there a better cipher that I could use (a more secure one that has a longer key maybe)?


There is no benefit to using a key that is larger than 256 bits. One of the only reasonable alternatives to AES-256-gcm would be a Salsa/ChaCha-poly1305 based construction. If you're concerned about side channel attacks, then it might be wise to switch. However, if the library you're using doesn't happen to support Salsa/ChaCha-poly1305 out of the box, then don't worry about it.


  Also why does aes-256-gcm accept a longer than 32 bytes key but on decryption it just ignores anything above the first 32 bytes of that key?


The algorithm is only defined to use key sizes of 128, 192, and 256 bits; You cannot simply supply more and expect them to be used. 

It is possible that the key length not being checked might lead to a bug somehow.


  Finally what is the best way to store the key for later usage


Here are some options:


Derive the key from a password on application startup
Split the key into $n$ secret shares and distribute them to a bunch of distinct servers


Retrieve the shares and recover the key on application startup

Store the key on a hardware device such as a flash drive
Make use of some kind of HSM (hardware security module) device.


The last option should easily be the most secure, but it will cost money. 

If you go with any option other than the HSM, do your best to ensure the key only stays in memory in one location and isn't copied all over the place. With an HSM this isn't a concern, as the key never leaves the HSM.