The core problem is that there is loss of range during implicit conversions.
When i
is used as the mysqli binding hint it effectively does (int)value
. In a 32-bit system the Session ID exceeds the maximum size of the PHP integer and overflows: (int)"100007810775829" -> -502711531
.
When s
is used, then mysqli does not do this conversion, but passes the value off directly to MySQL (as a string). In this case MySQL silently stores the maximum value it can for the field, which is 2147483647
for an INT column.
Thus, using s
with BIGINT field would "work" because:
- mysqli does not try to coerce the value to an integer
- MySQL BIGINT can store [-263, 263-1]
However, I recommend using a CHAR type instead. This is because the Session ID should be treated as an opaque identifier and not as a number - no math operations apply to it. In addition, simply using a CHAR may avoid silent implicit conversions in the future, such as when dealing with drivers which may incorrectly convert a BIGINT to an integer or float PHP value and thus (like this issue) result in loss of range or precision.