Unsigned int php imzaladı

4 Cevap php

Bu 32bit OS ip2long döner int imzaladı ve 64bit işletim imzasız int iade edilir, görünür.

Benim uygulama 10 sunucularında çalışıyor ve bazı 32bit ve 64bit bazıları vardır, bu yüzden onları aynı şekilde çalışması için tüm ihtiyaç.

PHP belgelerinde var ki sonuç her zaman imzasız yapmak için bir hile olduğunu, ama ben verilerin benim veritabanı zaten tam geldiğimden beri, ben o imzalı olmasını istiyorum.

Peki nasıl PHP imzalı birine imzasız bir int değiştirmek için?

4 Cevap

PHP bir türü olarak işaretsiz tamsayı desteklemez, ama ne yapabilirim sadece sprintf yorumlamak suretiyle imzasız bir int string içine ip2long sonucunu dönüyoruz değeri olarak imzasız %u:

 $ip="128.1.2.3";
 $signed=ip2long($ip);             // -2147417597 in this example
 $unsigned=sprintf("%u", $signed); //  2147549699 in this example

Düzen, gerçekten bile 64 bit sistemlerde imzalanacak istedim çünkü - burada 64 bit + 32 bit imzalı eşdeğer değer ettik dönüştürmek istiyorum nasıl:

$ip = ip2long($ip);
if (PHP_INT_SIZE == 8)
{
    if ($ip>0x7FFFFFFF)
    {
        $ip-=0x100000000;
    }
}

Eğer MySQL kullanıyorsanız FWIW, bu sadece veritabanı için dizeleri olarak IP'lerin geçmek ve MySQL INET_ATON (kullanarak dönüşüm yapalım eğer), genellikle çok daha kolay ve daha temiz (takarken / UPDAT (E) 'ing) ve inet_ntoa () (seçerken). MySQL burada anlatılan sorunlardan herhangi yoktur.

Örnekler:

SELECT INET_NTOA(ip_column) FROM t;

INSERT INTO t (ip_column) VALUES (INET_ATON('10.0.0.1'));

Sorguları da çok daha okunabilir.

MySQL bir INT UNSIGNED veri türü kullandığından beri PHP kullanır iken not, PHP ip2long () / long2ip () ile MySQL inet_ntoa () / INET_ATON () karıştırıp unutmayın bir {[(1)] } tamsayı. Karıştırma imzalı ve imzasız tamsayı pisliği verileri ciddiye olacak!

-Misunderstood sorun, yukarıda Paul Dixon cevaba bakınız.


64bit işaretsiz tamsayı teknik PHP5'ta desteklenmez. Bu yerli türünü kullanacak. Yüksek bit kaybetmeden int imzalı bir 64bit bir 32bit imzalı int dönüştürmek için, maske ve ardından çıkış döküm yazabilirsiniz:

$ip_int = ip2long($ip);
if (PHP_INT_SIZE == 8) // 64bit native
{
  $temp_int = (int)(0x7FFFFFFF & $ip_int);
  $temp_int |= (int)(0x80000000 & ($ip_int >> 32));
  $ip_int = $temp_int;
}

Biz yüksek bit kaldırıldı beri 64 bit sistemde, bu değeri ($ ip_int) baskı bir 'imzasız' tamsayı gösterecektir. Ancak bu çıktıyı almak ve istediğiniz nasıl saklamak için izin vermelidir.

32 ve 64 bit sistemlerde imzalı int gibi bir tamsayı değeri yorumlama:

function signedint32($value) {
    $i = (int)$value;
    if (PHP_INT_SIZE > 4)   // e.g. php 64bit
        if($i & 0x80000000) // is negative
            return $i - 0x100000000;
    return $i;
}