PHP strpos () аварийный скрипт - PullRequest
       8

PHP strpos () аварийный скрипт

1 голос
/ 07 сентября 2011

У меня есть PHP-скрипт, который ищет ссылки на странице, загружаемой с помощью функций CURL_MULTI.Загрузка в порядке, и я получаю данные, но мой скрипт случайно падает, когда я сталкиваюсь со страницей, в которой URL-адрес указан в качестве ссылки.Это код:

$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;
    }
}

Это пользовательский rev_strpos, который просто выполняет обратную операцию strpos():

// 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) );
}

, так что если:

$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.';

и

$supshorturl = "google.com";

Это должно найти позицию второго вхождения google.com, где он находится внутри HTML-тега href.Проблема в том, что он не сообщает об ошибке до сбоя, мои настройки ошибок:

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

Моя handle_errors() функция регистрирует все ошибки в файле.Однако об ошибках не сообщается до сбоя скрипта.Кроме того, мой curl_multi обрабатывает много URL-адресов, и иногда он падает на определенном URL-адресе, а иногда - на другом URL-адресе ... Я готов вырвать свои волосы, потому что это кажется таким простым делом ... но здесь яесть.Еще одно замечание: если я уберу цикл while, то не произойдет сбоя, также, если страница сначала содержит URL-адрес в теге href, то она не падает.Пожалуйста, помогите мне разобраться в этом.Спасибо миллион!

Ответы [ 2 ]

0 голосов
/ 07 сентября 2011

Я думаю, ты делаешь это сложнее, чем нужно.Если rev_strpos требуется только для возврата последнего экземпляра строки поиска, , и если вас не беспокоит случай , используйте вместо него strripos.

Из документов PHP ...

strripos - Найти позицию последнего появления строки без учета регистра в строке

Описание

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

Найти позицию последнего вхождения строки в строку.В отличие от strrpos (), strripos () нечувствителен к регистру.

Если вам нужно, чтобы он был чувствительным к регистру, или просто по какой-то причине хотите использовать собственную функцию, проблема в том, как вырассчитываем смещение.В частности, в этих 2 строках:

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

Используя ваш пример "Некоторый текст ..." и ища "google.com", если мы не указываем смещение, вычисляется смещение как длина (500chars) - offset (0 chars) - 1. Затем вы используете strpos для строки длиной 500 символов, начиная с символа смещения 499. Вы никогда не найдете ничего подобным.

Поскольку вы меняете направлениестог сена, а также ваша игла, вам нужно "повернуть" смещение.Измените строку на:

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

(На самом деле, вы должны изменить предыдущую строку, чтобы вычислить смещение $, где вы хотите, но вы получите точку ...)

ОБНОВЛЕНИЕ:

В дополнение к рекомендациям по использованию Regex очень просто получить местоположения:

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
//)

Это действительно должно быть предпочтительнееуловки петли rev_strpos & while.

0 голосов
/ 07 сентября 2011

Проблема в том, что эта ошибка синтаксического анализа

$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.";

... должна быть

$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.";
...