webForumDet fria alternativet

Sortera array på datum?

2 svar · 658 visningar · startad av Guldstrand

GuldstrandMedlem sedan juli 20041 271 inlägg
#1

Hur kan man sortera en array efter datum?
Har följande loop just nu:

foreach( $urls as $lankar){ 

$date1 = GetRemoteLastModified($lankar); 
$date2 = date("Y-m-d H:i", $date1); 

if ($date2 == "1970-01-01 01:00") $datum = "<span style=\"color: red\">uppgift saknas</span>";
else
$datum = "<span style=\"color: green\"><b>$date2</b></span>";

$color = ($color == '#D8D8D8') ? '#ffffff' : '#D8D8D8';

	print("<li style=\"background-color: $color\"><span>$datum</span><a href=\"$lankar\" target=\"_blank\">$lankar</a></li>\n");
}
print("</ul>\n");
nitro2k01Medlem sedan aug. 20039 342 inlägg
#2

Jag ska börja med att säga att om datat kommer från en databas är det nog en bättre idé att göra sorteringen redan i SQL-frågan, eftersom en databas är optimerad just för sådana uppgifter. Men om du absolut måste göra det i PHP går det att lösa med exempelvis usort. Applicera följande på arrayen innan utskrift.

function date_cmp_function($url1, $url2){
    return GetRemoteLastModified($url1) > GetRemoteLastModified($url2);
}

usort($urls, date_cmp_function);

Nu finns det dock ett problem med den metoden (och redan med den koden du använder.) Jag googlade efter GetRemoteLastModified och hittade följande snutt:

// get remote file last modification date (returns unix timestamp)
function GetRemoteLastModified( $uri )
{
    // default
    $unixtime = 0;
    
    $fp = fopen( $uri, "r" );
    if( !$fp ) {return;}
    
    $MetaData = stream_get_meta_data( $fp );
        
    foreach( $MetaData['wrapper_data'] as $response )
    {
        // case: redirection
        if( substr( strtolower($response), 0, 10 ) == 'location: ' )
        {
            $newUri = substr( $response, 10 );
            fclose( $fp );
            return GetRemoteLastModified( $newUri );
        }
        // case: last-modified
        elseif( substr( strtolower($response), 0, 15 ) == 'last-modified: ' )
        {
            $unixtime = strtotime( substr($response, 15) );
            break;
        }
    }
    fclose( $fp );
    return $unixtime;

Vid varje anrop av funktionen så startas en nerladdning av länken ifråga (även om nämnda nerladdning avslutas blixtsnabbt.) Sorteringsfunktionen kommer dessutom internt att anropa denna funktion flera gånger för varje länk. Det innebär både att din sida tar längre att ladda och att du anropar andra webbservrar i onödan.

Vad du egentligen bör göra är att lagra i databasen när du kollade en viss länk sist, och bara kolla den igen om det har gått längre än x tidsenheter sedan senaste kollen. Alltså, utforma koden så att varje länk enbart kollas en gång i timmen.

Ett första steg är dock följande kod som åtminstone bara anropar den andra servern en gång per sidladdning:

// Skyffla in i ny array som innehåller både URL och hämtad tid.
foreach($urls as $lank){  
    $urls2 = array(url => $lank, time => GetRemoteLastModified($lank));
}

// Sortera
function date_cmp_function($url1, $url2){
    return $url1['time'] > $url2['time'];
}

usort($urls, date_cmp_function);

// Utskrift
foreach($urls2 as $link){  

$date2 = date("Y-m-d H:i", $link['time']);  
$lankar = $link['url'];

if ($date2 == "1970-01-01 01:00") $datum = "<span style=\"color: red\">uppgift saknas</span>"; 
else 
$datum = "<span style=\"color: green\"><b>$date2</b></span>"; 

$color = ($color == '#D8D8D8') ? '#ffffff' : '#D8D8D8'; 

    print("<li style=\"background-color: $color\"><span>$datum</span><a href=\"$lankar\" target=\"_blank\">$lankar</a></li>\n"); 
} 
print("</ul>\n");

Sen dinns det annat som kan kommenteras kring din kod, men det får räcka för stunden.

GuldstrandMedlem sedan juli 20041 271 inlägg
#3

Ett stort tack! Ska testa med detta.
Nej, datan kommer inte från någon databas.

125 ms totalt · 3 externa anrop · v20260731065814-full.3ab8d573
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
123 ms — hämta tråd, inlägg och bilagor (db)