I vaguely understand the bit shifting required to set IV's.
Here's the C# code I use for, say, setting ATTIV:
uint i = rawdata.GetUInt(0x38);
i &= 0xFFFFFC1F;
uint val = (uint)(value << 5);
i |= val;
rawdata.SetUInt(0x38, i);
However, when I port the code to PHP, it gets mangled on most of them. Apparently, PHP's typing is rather awkward and numbers default to a signed integer, and all math is signed integers for the most part.
Currently, I'm attempting to use GMP as seen below:
$newIV = $row['AttIV'];
$i = substr($q,0x38,8);
$i = gmp_and($i , 0xFFFFFC1F);
$val = gmp_mul($newIV,gmp_pow(2,5));
$i = gmp_or($i, $val);
$i = pack("V", $i);
$q = substr($q,0,0x38).$i.substr($q,0x3C);
For reference, $q is the loaded pokemon.