Question

J'ai un script PHP qui cherche des liens sur une page qui télécharge des fonctions CURL_MULTI. Le téléchargement est très bien et je reçois les données, mais mon script se bloque au hasard quand je rencontre une page qui a l'URL indiquée comme nonlink. Voici le code:

$fishnof = strpos($nofresult, $supshorturl, 0);
$return[0] = ''; $return[1] = ''; // always good to cleanset

// Make sure we grabbed a link instead of a text url(no href)
if ($fishnof !== false) {
    $linkcheck = rev_strpos($nofresult,'href',$fishnof);
    $endthis = false;
    while($endthis !== true) {
        if($linkcheck > ($fishnof - 25)){ // 19 accounts for href="https://blog. 25 just in case
            $endthis = true;
            break;
        }
        $lastfishnof = $fishnof;
        $fishnof = strpos($nofresult,$supshorturl,$fishnof+1);
        if($fishnof === false){$fishnof = $lastfishnof;$linkcheck = rev_strpos($nofresult,'href',$fishnof);$endthis = true;break;}// This is the last occurance of our URL on this page
        if($linkcheck > $fishnof){$linkcheck = rev_strpos($nofresult,'href',$fishnof);$endthis = true;break;} // We went around past the end of the string(probably don't need this)      
        $linkcheck = rev_strpos($nofresult,'href',$fishnof);
    }
    if($linkcheck < ($fishnof - 25)){ // 19 accounts for href="https://blog. 25 just in case
        $return[0] = 'Non-link.';
        $return[1] = '-';
        $nofresult = NULL; // Clean up our memory
        unset($nofresult); // Clean up our memory
        return $return;
    }
}

Ce sont les rev_strpos personnalisés, qui fait juste un strpos() inverse:

// Does a reverse stripos()
function rev_strpos(&$haystack, $needle, $foffset = 0){
    $length = strlen($haystack);
    $offset = $length - $foffset - 1;
    $pos = strpos(strrev($haystack), strrev($needle), $offset);
    return ($pos === false)?false:( $length - $pos - strlen($needle) );
}

si:

$nofresult = '
Some text.Some text.Some text.Some text.Some text.Some text.
Some text.Some text.Some text.Some text.Some text.Some text.
Some text.Some text.Some text.Some text.Some text.Some text.
google.com Some text.Some text.Some text.Some text.Some text.
Some text.Some text.Some text.Some text.Some text.Some text.
Some text.Some text.Some text.Some text.Some text.Some text.
<a href="http://www.google.com">Google</a> Some text.Some text.
Some text.Some text.Some text.Some text.Some text.Some text.';

et

$supshorturl = "google.com";

Cela devrait trouver la position de la deuxième occurance de google.com, où il est à l'intérieur d'une balise href HTML. Le problème est qu'il ne signale pas d'erreur avant l'accident, mes paramètres d'erreur:

ini_set("display_errors", 1);
error_reporting(E_ALL & ~E_NOTICE);
set_error_handler('handle_errors');

Ma fonction handle_errors() enregistre toutes les erreurs dans un fichier. Toutefois, aucune des erreurs sont signalées avant que le script se bloque. Aussi mes processus curl_multi beaucoup d'URL, et parfois, il se bloque sur une certaine URL et et d'autres fois il se bloque sur une autre URL ... Je suis prêt à retirer mes cheveux parce que cela semble être une telle affaire facile ... mais ici, je un m. Un autre point de l'avis est si je retire la boucle while alors aucun accident, même si la page a l'url dans une balise href d'abord, puis il ne tombe pas en panne. S'il vous plaît me aider à cette chose. Merci un million!

Était-ce utile?

La solution

Je pense que vous rendre plus difficile qu'il doit être. Si rev_strpos seulement nécessaire pour retourner la dernière instance de votre chaîne de recherche, et si vous n'êtes pas inquiet cas , utilisez strripos à la place.

A partir de la documentation PHP ...

strripos - Recherche la dernière occurrence d'une chaîne insensible à la casse dans une chaîne

Description

int strripos ( string $haystack , string $needle [, int $offset = 0 ] )

Trouve la position de la dernière occurrence d'une chaîne dans une chaîne. Contrairement à strrpos (), strripos () est insensible à la casse.

Si vous avez besoin pour être sensible à la casse, ou tout simplement à utiliser votre propre fonction pour une raison quelconque, le problème est dans la façon dont vous calculez le décalage. Plus précisément dans ces 2 lignes:

$offset = $length - $foffset - 1;
$pos = strpos(strrev($haystack), strrev($needle), $offset);

Utilisation de votre échantillon « Un texte ... » et la recherche de « google.com », si nous ne précisons pas un décalage calcule le décalage que la longueur (500 caractères) - décalage (0 caractères) - 1. Ensuite, vous utilisez strpos sur une chaîne de longueur 500-char à partir de décalage en caractères 499. vous ne réussirez jamais à trouver quoi que ce soit de cette façon.

Puisque vous inversez votre botte de foin et aussi votre aiguille, vous devez « inverser » votre offset. Modifiez la ligne:

$pos = strpos(strrev($haystack), strrev($needle), $length - $offset);

(En fait, vous devriez changer votre ligne avant de calculer le décalage où $ vous voulez qu'il soit, mais vous obtenez le point ...)

Mise à jour:

Suite aux recommandations sur l'utilisation Regex, il est vraiment trivial pour obtenir des emplacements:

function getOffsets( $url, $baseRegex, $text ){
    $results = array();
    $regex= str_replace( '%URL%', $url, $baseRegex );
    preg_match_all( $regex, $text, $matches, PREG_OFFSET_CAPTURE );

    foreach ( $matches[0] as $match )
        array_push( $results, ($match[1] + strpos( $match[0], $url )) );

    return $results;
}

$linkRegex = '/<a[^>]*href="[^"]*%URL%[^"]*"[^>]*>/i';
$linkLocations = getOffsets( $url, $linkRegex, $text );
//Array
//(
//    [0] => 395
//)

$anyRegex = '/%URL%/i';
$allLocations = getOffsets( $url, $anyRegex, $text );
$nonlinkLocations = array_diff( $allLocations, $linkLocations );  //all non-links
//Array
//(
//    [0] => 188
//)

Cela devrait vraiment être préférable aux gimmicks boucle rev_strpos & while.

Autres conseils

Le problème est cette erreur d'analyse syntaxique

$nofresult = "
Some text.Some text.Some text.Some text.Some text.Some text.
Some text.Some text.Some text.Some text.Some text.Some text.
Some text.Some text.Some text.Some text.Some text.Some text.
google.com Some text.Some text.Some text.Some text.Some text.
Some text.Some text.Some text.Some text.Some text.Some text.
Some text.Some text.Some text.Some text.Some text.Some text.
<a href="http://www.google.com">Google</a> Some text.Some text.
Some text.Some text.Some text.Some text.Some text.Some text.";

... il devrait être

$nofresult = "
Some text.Some text.Some text.Some text.Some text.Some text.
Some text.Some text.Some text.Some text.Some text.Some text.
Some text.Some text.Some text.Some text.Some text.Some text.
google.com Some text.Some text.Some text.Some text.Some text.
Some text.Some text.Some text.Some text.Some text.Some text.
Some text.Some text.Some text.Some text.Some text.Some text.
<a href=\"http://www.google.com\">Google</a> Some text.Some text.
Some text.Some text.Some text.Some text.Some text.Some text.";
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top