Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP + MySQL] długość typu całkowitego
Forum PHP.pl > Forum > PHP
MySQL
Właśnie czytam dokumentację PHP i zauważyłem pewną rozbieżność informacji. W opisie funkcji date() jest napisane:
Cytat
The optional timestamp parameter is an integer...
natomiast przy opisie funkcji mktime() możemy przeczytać:
Cytat
Returns the Unix timestamp corresponding to the arguments given. This timestamp is a long integer...


I w związku z tym mam dwa pytania:

1. To w końcu jakiego typu jest ten UNIX'owy znacznik czasu? Nie słyszałem żeby PHP miał typ long integer.

2. Jakiego typu danych powinno być pole w bazie, które miałoby przechowywać ten znacznik czasu? Przeczytałm że jest to ilość sekund od 1 stycznia 1970 00:00:00. INTEGER czy BIGINT oraz SIGNED czy UNSIGNED?
MWL
  1. <?php
  2. vardump(time());
  3. ?>
MySQL
Ok. Pokazało mi się w oknie przeglądarki coś takiego:
Cytat
int(1236451321)


Rozmiem, żę to w tych nawiasach to jest wartość funkcji time w tym przypadku, a int to typ zwracany przez tą funkcję (jeżeli się mylę to proszę o poprawienie). 

To teraz jeszcze drugie pytanie. Czy do przechowywania w bazie MySQL znacznika czasu wystarczy pole typu INTEGER (4 bajty) czy trzeba dać BIGINT (8 bajtów)? Oraz SIGNED czy UNSIGNED?

A tak w ogóle czy typ integer (PHP) jest w stanie pomieścić typ BIGINT (MySQL)?

Ile w ogóle bajtów zajmuje typ integer w php (bo chyba musi ileś tam ich zajmować)? Wiem, że PHP jest językiem interpretowanycm ale interpreter musi przecież zmapować wszystie liczby na miejsce w pamięci czyli ileś tam bajtów one zajmują.
Mephistofeles
Napewno unsigned (bez znaku przecież masz datę). Wystarczy INT - zostanie ci jeszcze miejsca na sporo lat winksmiley.jpg.
MySQL
O ile z drugim Twoim zdaniem się zgadzam ;) to już do pierwszego mam dylemat. Na TEJ stronie jest napisane:

Cytat
Kiedy jest to możliwe, powinno się przechowywać dane jako liczby, ponieważ przeszukiwanie i sortowanie ich jest szybsze. Na przykład adres IP może zostać przechowany w formie:

123.123.123.123

dzięki użyciu VARCHAR(15). Jeśli zostanie on przetłumaczony na adres sieciowy protokołu IPv4 (dzięki użyciu np. funkcji ip2long() w PHP), może zostać zachowany jako:

2071690107

w polu SIGNED INT.


Sam widzisz... Adres IP też się składa wyłącznie z liczb nieujemnych ale zaleca się aby pole w bazie danych, które miałoby przechowywać taką liczbę było typu SIGNED. 
Mephistofeles
No i po co signed?
Orkan
ip2long" title="Zobacz w manualu PHP" target="_manual daje zawsze liczbe dodatnia wiec pole UNSIGNED. Dla bardziej dociekliwych ta funkcja nigdy nie zwroci Int'a dluzszego niz 10 cyfr wiec moznaby sie pokusic o typ UNSIGNED INT(10)

timestamp - moze przybierac wartosci ujemne dla daty sprzed ('1970-01-01 00:00:00' UTC) wiec pole SIGNED


Jak na moj chlopski rozum to typ long w php oznacza tyle co unsigned int i nic poza tym. Na upowszechnienie systemow 64bitowych trzeba chyba jeszcze troche poczekac smile.gif

A tak na marginesie to ciekawe czemu mySQL nie wspiera adresow IP tak jak to robi z datą? Napewno ulatwilo by to zycie niejednemu programiscie...
Inna sprawa to fakt rzutowania typow na unsigned int przy pomocy sprintf('%u',... w PHP. Troche lamersko wyglada, IMO winksmiley.jpg
Zyx
W PHP nie istnieje coś takiego, jak "typ całkowitoliczbowy bez znaku". Integer jest zawsze 4-bajtowy i zawsze signed, nie ma od tego żadnych wyjątków. Tak więc wszystkie te kombinacje w dokumentacji oznaczają w przypadku PHP jedno i dokładnie to samo.

- Unix timestamp jest w systemach uniksowych tradycyjnie typem signed integer, umożliwiając reprezentowanie dat od końca 1901 roku do początku 1970 (wartości ujemne) oraz od 1970 do 2038 (wartości dodatnie), przy czym w niektórych systemach typ time_t jest ostatnio wydłużany do 64 bitów.
- ip2long() zwraca wartość signed, bo nie może inaczej bez ucięcia połowy puli adresów. Wykorzystywane są wszystkie 32 bity i połowa istniejących adresów IPv4 da wartość ujemną. Przykładowo, 255.255.255.255 ma wartość -1. Konwersja na liczbę bez znaku (ale jedynie w formie tekstowej) jest możliwa dopiero poprzez przełącznik %u w printf() lub podobnych.
Orkan
Cytat(Zyx @ 8.03.2009, 09:44:10 ) *
- ip2long() zwraca wartość signed, bo nie może inaczej bez ucięcia połowy puli adresów. Wykorzystywane są wszystkie 32 bity i połowa istniejących adresów IPv4 da wartość ujemną. Przykładowo, 255.255.255.255 ma wartość -1. Konwersja na liczbę bez znaku (ale jedynie w formie tekstowej) jest możliwa dopiero poprzez przełącznik %u w printf() lub podobnych.


Pozwol ze nie do konca sie z Toba zgodze.
Czy dana liczba Int jest ze znakiem czy bez jest umowne. Tzn. ten sam zapis binarny (w ramach 32bitowej liczby) moze oznaczas dwie rozne liczby. Najprostszym przykladem jest tu liczba -1, 0xFFFFFFFF (hex) moze rowniez oznaczac liczbe 4294967295 jesli przyjąć typ UNSIGNED.

ip2long zwraca liczbe calkowitą dodatnią, bo na podstawie obliczen jakie wykonuje, nie mialoby sensu aby wyszla z tego liczba ujemna. Więc umieszczając wynik ip2long() w polu UNSIGNED INT (po rzutowaniu %u w printf()) mamy pewnosc ze typ jest wlasciwy co do oczekiwan. Oczywiście, nic sie nie stanie (a nawet jest tak latwiej) jesli to pole bedzie SIGNED bo dalej operujemy na liczbie 4-bajtowej.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.