PHP has two random number implementations at the moment rand() and mt_rand(), the former being a wrapper around the libc rand function and the latter being a implementation of the Mersenne Twister algorithm. Both of these are reasonable for generating random numbers but due to the fact that they're only seeded with a 32-bit number they are not suitable for cryptographic purposes.
Stefan Esser has a good article about the common pitfalls that most application developers fall into it when attempting to generate random values.
Most operating systems provide some sort of random number functionality, on Windows we have the CryptoAPI which samples various bits of information about the system creating a system wide seed. This includes monitoring the system counter, free disk clusters, memory status and other process information. With most varieties of Linux we have /dev/random which collects noise from device drivers and on some of the BSD based systems there is arc4random.
With all these potential different ways to get some pseudo random data it would be hard to do this in native PHP. Now we could do this in C and implement all the code ourselves but why risk implementing our own random functions and potentially making a mistake?
The answer is OpenSSL, we already have an OpenSSL module and obviously they have some random functionality built in for when you go to generate SSL certificates. So from PHP 5.3 access to the OpenSSL random number generator.
string openssl_random_pseudo_bytes(integer length [, &bool strong_result])
The return value and first parameter of this function should be pretty straight forward, you pass in a length and the random number generator returns a string of this length.
$random = openssl_random_pseudo_bytes(512);
On error this function will return false, the second parameter is a reference to a variable that will be set to true if the result is cryptographically strong.
$random = openssl_random_pseudo_bytes(512, $strong);
If $strong is true then the value of $random is considered cryptographically secure, if you don't care then just ignore the second parameter.