Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: PHP: Linkkien tulostaja/tarkastaja

kayttaja-2791 [15.04.2005 16:15:13]

#

Hakee sivun lähdekoodista linkit. Optiona on myös palauttaa kaikkien linkkien html headerit.
Eli käytännön hyötyäkin tästä on, voit tarkastaa minkä tahansa sivun linkkien toimivuuden.

Alunperin lähdetty kehittämään Antti Laaksosen Regexpistä joka tuli esille jossain Ohjelmointiputkan keskustelualueella. Kaikki kunnia siitä hänelle.
Sanoin get_headers funktio ei ole omani vaan se on kopioitu PHP:n manuaalista.

Ver3: 14.09.2005 - Parannettu huomattavasti
-Tukee <area linkkejä (vielä puutteellinen)
-Tukee kuvia linkeissä

<?php
/*
Hakee sivun lähdekoodista linkit. Optiona on myös palauttaa kaikkien linkkien html headerit.
Eli käytännön hyötyäkin tästä on, voit tarkastaa minkä tahansa sivun linkkien toimivuuden.

Alunperin lähdetty kehittämään Antti Laaksosen Regexpistä. Kaikki kunnia siitä hänelle.
Samoin get_headers funktio ei ole omani vaan se on kopioitu PHP:n manuaalista.

Ver3: 14.09.2005 - Lisätty tuki arealle, muutenkin viimeistelty
*/
?>
<a href="?source=1">Näytä source</a> -
<a href="?osoite=<?php echo urlencode($_GET['osoite'])?>&showheaders=true">Näytä html headerit</a> (Varoitus! Raskas, hidas, tekee kymmenittäin yhteyksiä!)
<form>
<input type="text" name="osoite" value="<?php echo $_GET['osoite']?>" size=40>
<input type="submit">
</form>
<?php
if ($_GET["source"] == true) //Näytetään source
    show_source(__FILE__);
else {
    //Tämä on PHP5:sen funktio jolla tarkastetaan html headerit, PHP:n manuaalista kopioitu tämä PHP4 versio
    if(!function_exists('get_headers')) {

       /**
       * @return array
       * @param string $url
       * @param int $format
       * @desc Fetches all the headers
       * @author cpurruc fh-landshut de
       * @modified by dotpointer
       * @modified by aeontech
       */
       function get_headers($url,$format=0)
       {
           $url_info=parse_url($url);
           $port = isset($url_info['port']) ? $url_info['port'] : 80;
           $fp=fsockopen($url_info['host'], $port, $errno, $errstr, 30);

           if($fp)
           {
               $head = "HEAD ".@$url_info['path']."?".@$url_info['query']." HTTP/1.0\r\nHost: ".@$url_info['host']."\r\n\r\n";
               fputs($fp, $head);
               while(!feof($fp))
               {
                   if($header=trim(fgets($fp, 1024)))
                   {
                       if($format == 1)
                       {
                           $key = array_shift(explode(':',$header));
                           // the first element is the http header type, such as HTTP 200 OK,
                           // it doesn't have a separate name, so we have to check for it.
                           if($key == $header)
                           {
                               $headers[] = $header;
                           }
                           else
                           {
                               $headers[$key]=substr($header,strlen($key)+2);
                           }
                           unset($key);
                       }
                       else
                       {
                           $headers[] = $header;
                       }
                   }
               }
               return $headers;
           }
           else
           {
               return false;
           }
       }
    }

    if ($_GET['showheaders'])
        $htmlheaders = $_GET['showheaders'];
    $osoite = $_GET['osoite'];
    if (substr($osoite, 0, 7) == "http://")
      $websivu = @file_get_contents($osoite);
  else
    $osoite = "http://".$osoite;
    $websivu = @file_get_contents($osoite);
  if ($websivu === false)
    exit("Tietojen hakeminen sivulta $osoite epäonnistui, tarkistathan että kirjoitit osoitteen oikein.");

    /*
    Funktio jolle annettaessa lähde ($sivu) ja sen osoite ($osoite) palauttaa se taulukossa sivun linkit.
    Linkit ovat taulukossa muodossa $linkit[1] on osoite, $linkit[2] on sen sisällä oleva teksti.
    $linkit[0] kohdassa on koko <a href="... roska
    */
    function getlinks($sivu, $osoite = 0) {
        //Jos pääte on jokin näistä niin poistetaan lopusta viimeisen / merkin jälkeen kaikki... Kiitos T.M:lle tämän bugin löytämisestä
        //Koodi ei ole kaunista, samoja muuttujia on käytetty monesti. Anteeksi siitä, ehkä kirjoittelen koodin vielä uusiksi
        $päätteet = array("html", "htm", "php", "php4", "php3", "asp", "jsp", "txt");
        $exploded = explode(".", $osoite);
        $pääte = array_slice($exploded, -1);
        $pääte = $pääte[0];
        //Eli mikäli osoite päättyy johonkin edellämainituista päätteistä tai sisältää ? merkin poistetaan kaikki viimeisen / merkin jälkeen
        if (in_array($pääte, $päätteet) or strpos($osoite, "?")) {
            $exploded = explode("/", $osoite);
            $exploded = array_slice($exploded,0, count($exploded) - 1);
            $osoite = implode("/", $exploded);
        }
        preg_match_all("/<a[^>]*href=[\"']([^\"']+)[\"'][^>]*>(.*)<\\/a>/i", $sivu, $linkit); //Haetaan linkit, tämän regexpin on käytännössä kokonaan tehnyt Antti Laaksonen

        //Haetaan myös <area tyyppiset linkit ja lisätään nekin listaan
        preg_match_all("/<area[^>]*href=[\"']([^\"']+)[\"'][^>]*alt=[\"']([^\"']+)[\"'][^>]*>/i", $sivu, $arealinkit);
        preg_match_all("/<area[^>]*href=[\"']([^\"']+)[\"'][^>]*alt=[\"']([^\"']+)[\"'][^>]*>/i", $sivu, $arealinkit);
        foreach ($arealinkit[1] as $key => $value) {
      $linkit[1][] = $value;
      $linkit[2][] = $arealinkit[2][$key];
    }
        //Tässä yhdistetään suhteelliset linkit, tämä on vielä kesken. Eli muuttaa linkit /keskustelualue muotoon https://www.ohjelmointiputka.net/keskustelualue
        foreach ($linkit[1] as $key => $url) {
            //Mikäli ei ala http:// niin laitetaan alkuperäinen osoite eteen, eikä se myöskään ala mailto:
            if (substr($url, 0, 7) !== "http://" && substr($url, 0, 7) !== "mailto:" && substr($url, 0, 8) !== "https://") {

                /*Mikäli alkuperäinen osoite ei pääty / merkkiin pitää se sinne laittaa,
                ja toisaalta mikäli linkit sisältävät jo alussa / merkin*/
                if (substr($osoite, -1) <> "/" && substr($url, 0, 1) <> "/")
                    $osoite .= "/";

                //Mikäli sekä linkkien alut että osoitteen loppu sisältävät / merkin pitää toinen poistaa
                elseif (substr($osoite, -1) == "/" && substr($url, 0, 1) == "/")
                    $osoite = substr($osoite, 0, -1);
                //Mikäli sivuilla on suhteellisia linkkejä kuten <a href="/testit/oraakkeli/"> tulee alkuperäistä osoitetta kursia
                if (substr($url, 0, 1) == "/") {
                    $exploded = explode("/", $osoite);
                    $osoite = $exploded[0]."/".$exploded[1]."/".$exploded[2];
                    unset($exploded);
                }
                //poistetaan ./ merkinnät...
                $url = preg_replace("/[^\\.]?\\.\\//i", "", $url);
                $linkit[1][$key] = $osoite.$url;
            }
            //Poistetaan kuvat kuvauksista
            if (strpos($linkit[2][$key], "<img") !== false) {
        //Otetaan kuvan alt- tai title-teksti
        if (preg_match("/^<img[^>]*>$/i", $linkit[2][$key])) {
          preg_match("/(alt|title)=[\"']([^\"']+)[\"']/i", $linkit[2][$key], $imgalt);
          $linkit[2][$key] = $imgalt[2];
        }
        //On muutenkin tekstiä, poistetaan vain kuva
        else {
          $linkit[2][$key] = preg_replace("/(<img[^>]*>)/i", "", $linkit[2][$key]);
        }
      }
        }
        return $linkit;
    }
    $linkit = getlinks($websivu, $osoite);
    //Sitten tulostetaan koko roska
    $lukumäärä = count($linkit[1]);
    echo "Löytyi yhteensä <i>{$lukumäärä}</i> linkkiä";
    echo "\n\n<table>\n<tr><td><b>Osoite</b></td><td><b>Teksti</b></td>";
    if ($htmlheaders)
            echo "<td><b>Html header</b></td>";
    echo "</tr>\n";
    for ($i = 0; $i < $lukumäärä; $i++) {
        if ($htmlheaders && substr($linkit[1][$i], 0, 7) == "http://")
            $htmlheader = get_headers($linkit[1][$i]);
        else
            $htmlheader[0] = "Ei haettu";
        echo "<tr><td><a href=\"?osoite={$linkit[1][$i]}\">{$linkit[1][$i]}</a></td><td>{$linkit[2][$i]}</td>";
        if ($htmlheaders)
            echo "<td>{$htmlheader[0]}</td>";
        echo "</tr>\n";
    }

    echo "</table>";
}
?>

T.M. [17.04.2005 19:14:26]

#

Näyttäisi toimivan hienosti :)
Paitsi jos laittaa sivun muotoon: http://keijo.com/index.php?jotain=tassa

Ärm, ei toi olekaan se syy, tuo sekoilee ainakin minulla:
http://koti.mbnet.fi/winuus/index.php
ja sit ku etin linkit, ni tulee:
http://koti.mbnet.fi/winuus/index.php/text.php

kayttaja-2791 [17.04.2005 19:39:30]

#

No piru. Syytän tästä laiskoja beta-testaajia :|

Korjaus luvassa, joskus.

Edit:
Korjattu

T.M. [17.04.2005 21:35:45]

#

Löysin vielä yhden bugin:

?osoite=http://koti.mbnet.fi

kayttaja-2791 [20.04.2005 12:06:10]

#

Ja toisen (kun painelee edellisen päivän ja tämän päivän pelin välillä):

?osoite=http://www.mbnet.fi/jutut/paivanpeli/././././

Ape [27.04.2005 19:28:30]

#

Jos laittaa väärän osoitteen tulee virhe. Eikö siihen voisi laittaa "vaikka sivua ei löydy".
EDIT: Warning: file_get_contents(\"väärä_osoite\"): failed to open stream: No such file or directory in .../public_html/temp/tutkija/index.php on line 82

kayttaja-2791 [14.09.2005 22:53:47]

#

Bugit korjattu ja uusia ominaisuuksia lisätty. Tosin en ole oikein tyytyväinen nyt tähän rakenteeseen, se on aika purkkaa. Ehkä uusi, perusteellinen remontti on vielä edessä...

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta