$pobranie_numerow_z_users = $db->query("SELECT `number` FROM `users` WHERE `zgoda` = '0' AND `globalban` = '0'");
$la = $pobranie_numerow_z_users->num_rows;
w tym kodzie pobierasz numery i sprawdzasz ile ich jest, ustawiajac warunek $la, a warunkiem wyjscia z całej pętli jest sytuacja kiedy ich liczba bedzie mniejsza od zera bądź większa od tysiąca
while($la > 0 && $la <= 1000);
natomiast nie robisz nic co sprawiłoby że pierwszy select miałby zwrócić mniej bądź wiecej numerów tj. updateujesz pola:
$q = $db->query("UPDATE `users` SET `wyslano` = '1' WHERE `globalban` = '0' AND `wyslano` = '0' AND `zgoda` = '0'");
ale nie zmieniasz nic co mogłoby wpłynąć na wynik warunku wyjścia z pętli, myslę że źle wziąłeś się za pętle która miała się przeiterować przez wszystkie numery. poniżej moja wersja twojego kodu przy założeniach które podałeś (nie znam struktury twoich danych ale mysle ze będzie ok)
$staff = 50;
$tekst = 'test';
$pobranie_numerow_z_users = $db->query("SELECT * FROM `users` WHERE `zgoda` = '0' AND `globalban` = '0'");
$la = $pobranie_numerow_z_users->num_rows;
//sprawdzenie zakresu
if ($la > 0 && $la <= 1000) {
//iteracja przez wszystkie wyniki
while($pnu = $pobranie_numerow_z_users->fetch_assoc())
{
$pobranie_numerow_z_whois = $db->query("SELECT * FROM `whois` WHERE `ranga` >= {$staff} AND `number` = '".$pnu['number']."'");
while($pnw = $pobranie_numerow_z_whois->fetch_assoc())
{
$nr[] = $pnw['number'];
}
$tekst->allsay($co, $tekst, $nr);
$q = $db->query("UPDATE `users` SET `wyslano` = '1' WHERE `globalban` = '0' AND `wyslano` = '0' AND `zgoda` = '0'");
}
//to jest w sumie niepotrzebne, po co sleep na 1 sekunde?
//zakładając że wysyłasz maile to i tak wysyłasz do potencjalnie różnych nadawców
//chyba że twój serwer jest uznany za spamerski, ale w takim wypadku
//i tak wiadomość nie dotrze
}
ps. tak jak kolega już wspomniał, popracuj nad formatowaniem bo za rok, dwa będziesz rwał włosy z głowy próbujac doszukać się zależności w kodzie