Фатальная ошибка

84
22 марта 2022, 21:30

Есть у меня парсер музыки с ВК, так вот, он перестал работать, в чём может быть проблема?

Fatal error: Uncaught TypeError: Argument 1 passed to DOMXPath::__construct() must be an instance of DOMDocument, null given in /var/www/data/www/site.ru/audio/core/class.vkParser.php:51 Stack trace: #0 /var/www/data/www/site.ru/audio/core/class.vkParser.php(51): DOMXPath->__construct(NULL) #1 /var/www/data/www/site.ru/audio/index.php(10): vkParser->getUser() #2 {main} thrown in /var/www/data/www/site.ru/audio/core/class.vkParser.php on line 51

Вот 51 строка этого кода:

$domxpath = new DOMXPath($doc);

Помогите, пожалуйста :)

Полный код этого файла:

<?php

if(! defined('FILE_CACHE_MAX_FILE_AGE') ) define ('FILE_CACHE_MAX_FILE_AGE', 21600); class vkParser { private $strlUrl, $ch; private $httpUserAgent = 'Mozilla/5.0 Windows NT 6.1; Win64; x64 AppleWebKit/537.36 KHTML, like Gecko Chrome/61.0.3163.91 Safari/537.36'; private $html, $action, $doc; private static $response = []; private static $i = 0;

public function __construct($strUrl, $type = true)
{
    if(is_readable(__DIR__ . '/cookie/cookieUserVk.cook') === false)
        exit(header('Location: /audio/auth'));
    $this->strUrl = $strUrl;
    $this->ch     = curl_init();
    $options      = [
            CURLOPT_URL            => $this->strUrl,
            CURLOPT_USERAGENT      => $this->httpUserAgent,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_TIMEOUT        => 15,
            CURLOPT_FAILONERROR    => true,
            CURLOPT_REFERER        => 'https://m.vk.com',
            CURLOPT_COOKIEFILE     => __DIR__ . '/cookie/cookieUserVk.cook',
        ];
    if(is_dir(__DIR__ . '/cookie') === false)
    {
        mkdir(__DIR__ . '/cookie');
        file_put_contents(__DIR__ . '/cookie/.htaccess', 'Deny From All');
    }
    if(is_dir(__DIR__ . '/response') === false)
    {
        mkdir(__DIR__ . '/response');
        file_put_contents(__DIR__ . '/response/.htaccess', 'Deny From All');
    }
    curl_setopt_array($this->ch, $options); 
        $this->_exec();
    if(!empty($this->html))
    {
        $this->doc = new DOMDocument();
        $this->_newHtmlDoc();
    }
    $this->cleanDirFile();
}
public function getUser()
{
    $doc  = &$this->doc;
    $domxpath = new DOMXPath($doc);
    $element = $domxpath->query("//div[@class='op_fcont']/h2[@class='op_header']/a[@class='op_owner']");
    if ($element->length <= 0)
        return false;
    $element = $element->item(0);
    return [
        'name' => $element->getAttribute('data-name'),
        'photo' => $element->getAttribute('data-photo'),
        'url' => 'https://vk.com' . $element->getAttribute('href')
    ];
}
public function fetchMulti($strUrl)
{
    $Url = [
        $strUrl . '&offset=0',
        $strUrl . '&offset=50',
        $strUrl . '&offset=100',
        $strUrl . '&offset=150',
    ];
    $multi = curl_multi_init();
    $ch = [];
    foreach($Url As $key => $item)
    {
        $ch[$key] = curl_init();
        $options  = [
            CURLOPT_URL            => $item,
            CURLOPT_USERAGENT      => $this->httpUserAgent,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_TIMEOUT        => 15,
            CURLOPT_FAILONERROR    => true,
            CURLOPT_REFERER        => 'https://m.vk.com',
            CURLOPT_COOKIEFILE     => __DIR__ . '/cookie/cookieUserVk.cook',
        ];
        curl_setopt_array($ch[$key], $options); 
        curl_multi_add_handle($multi, $ch[$key]);
    }
    $active = null;
    do
        $mrc = curl_multi_exec($multi, $active);
    while ($mrc == CURLM_CALL_MULTI_PERFORM);
    while ($active && $mrc == CURLM_OK) 
    {
        if (curl_multi_select($multi) == -1)
            continue;
        do 
            $mrc = curl_multi_exec($multi, $active);
        while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
    /*$running = null;
    do {
      curl_multi_exec($multi, $running);
      curl_multi_select($multi);
    } while ($running > 0);*/
    foreach ($ch as $key => $item) 
    {
        $this->html = curl_multi_getcontent($ch[$key]);
        $this->_newHtmlDoc();
        $domxpath = new DOMXPath($this->doc);
        $elements = $domxpath->query("//div[@class='audios_block audios_list _si_container']");
        $this->parse($elements);
        curl_multi_remove_handle($multi, $ch[$key]);
    }
    curl_multi_close($multi);
}
public function fetch($strUrl)
{
    curl_setopt($this->ch, CURLOPT_URL, $strUrl);
    $this->_exec();
    $this->_newHtmlDoc();
    $domxpath = new DOMXPath($this->doc);
    $elements = $domxpath->query("//div[@class='audios_block audios_list _si_container']");
    $this->parse($elements);
    $elements = $domxpath->query("//a[@class='show_more']");
    if(self::$i <= 150 && $elements->length > 0)
        return $this->fetch('https://m.vk.com' . $elements->item(0)->getAttribute('href'));
    return true;
}
private function parse($elements)
{
    if($elements->length > 0)
    {
        foreach($elements->item(0)->childNodes AS $item)
        {
            if($item instanceof DOMElement)
            {
                self::$i = substr($item->getAttribute('data-id'), 1); // data-id
                if($item->childNodes->item(1) instanceof DOMElement) // ai_info
                {
                    //self::$response[self::$i]['image'] = substr($item->childNodes->item(1)->childNodes->item(1)->getAttribute('style'), 21, -1);
                    if($item->childNodes->item(1)->childNodes->item(5) instanceof DOMElement) // ai_body
                    {
                        $ai_body = $item->childNodes->item(1)->childNodes->item(5)->childNodes;
                        if(empty($ai_body->item(5)->getAttribute('value')))
                            continue;
                        self::$response[self::$i]['dur'] = $ai_body->item(1)->getAttribute('data-dur'); // ai_dur
                        self::$response[self::$i]['cDur'] = $ai_body->item(1)->textContent; // convert_dur
                        // ai_label
                        self::$response[self::$i]['title'] = $ai_body->item(3)->childNodes->item(1)->textContent; // ai_title
                        self::$response[self::$i]['artist'] = $ai_body->item(3)->childNodes->item(5)->textContent; // ai_artist
                        //file
                        self::$response[self::$i]['url'] = $ai_body->item(5)->getAttribute('value'); // ai_file
                        self::$response[self::$i]['file'] = mt_rand() . '-' . mt_rand() . '.mp3'; // ai_file
                    }
                }
                //self::$i++;
            }
        }
    }
}
private function cleanDirFile()
{
    $fileDIR = $_SERVER['DOCUMENT_ROOT'] . '/audio/file/';
    foreach(glob($fileDIR . $_SESSION['audioSession'] .'*.mp3') AS $item)
        unlink($item);
    if(is_readable($fileDIR . 'lastCleanTime.touch') === false)
        touch($fileDIR . 'lastCleanTime.touch');
    $timeAgo = time() - 4000;
    if(filemtime($fileDIR . 'lastCleanTime.touch') < $timeAgo)
    {
        foreach(glob($fileDIR . '*.mp3') AS $item)
            if(filemtime($item) < $timeAgo)
                unlink($item);
        touch($fileDIR . 'lastCleanTime.touch');
    }
}
public function isDataResponse($file)
{
    $file = md5(strtolower($file));
    $cachefile = __DIR__ . '/response/' . $file . '.data.r';
    $timeAgo = time() - FILE_CACHE_MAX_FILE_AGE;
    $data = [];
    if(is_readable($cachefile))
        $data = include $cachefile;
    if(empty($data) === true || (is_readable($cachefile) === true && filemtime($cachefile) < $timeAgo))
        return true;
    return false;
}
public function getDataResponse($file)
{
    $file = md5(strtolower($file));
    $cachefile = __DIR__ . '/response/' . $file . '.data.r';
    if(is_readable($cachefile) === false)
        return [
            'nameFile' => "",
            'response' => []
        ];
    return include $cachefile;
}
public function writeDataResponse($file)
{
    $file = md5(strtolower($file));
    $cachefile = __DIR__ . '/response/' . $file . '.data.r';
    if($this->isDataResponse($file))
        file_put_contents($cachefile,  '<?php return ' . var_export([
            'nameFile' => $file,
            'response' => self::$response
        ], true) . ';');
    return true;
}
private function _newHtmlDoc()
{
    if(!empty($this->html))
    {
        $old_libxml_error = libxml_use_internal_errors(true);
        $this->doc->loadHTML($this->html);
        libxml_use_internal_errors($old_libxml_error);
    }
}

private function _exec() 
{
    $options = [
        CURLOPT_HEADER         => true,
        CURLOPT_USERAGENT      => $this->httpUserAgent,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_TIMEOUT        => 15,
        CURLOPT_FAILONERROR    => true,
        CURLOPT_REFERER        => 'https://m.vk.com',
    ];
    curl_setopt_array($this->ch, $options); 
    $this->html = curl_exec($this->ch);
    if($this->html === false)
        return false;
    $http_code = curl_getinfo($this->ch, CURLINFO_HTTP_CODE);
    if ($http_code == 301 || $http_code == 302) 
    {
        list($header) = explode("\r\n\r\n", $this->html, 2);
        $matches = array();
        $header = preg_replace('#(Location:|URI:)\s/#i', 'Location: https://m.vk.com', $header);
        preg_match('/(Location:|URI:)(.*?)\n/', $header, $matches);
        $url = trim(array_pop($matches));
        $url_parsed = parse_url($url);
        if (!empty($url_parsed)) 
        {
            curl_setopt($this->ch, CURLOPT_URL, $url);
            $this->_exec();
            return true;
        }
    }
    list(,$body) = explode("\r\n\r\n", $this->html, 2);
    $this->html = $body;
    return true;
}
public function __destruct()
{
    curl_close($this->ch);
    $this->doc = null;
}

}

?>

Answer 1

Переменная $doc должна быть объектом DOMDocument, у вас она содержит null, об этом и говорит ошибка.

Вот в этом куске кода у вас стоит проверка, что если переменная html не пустая тогда создается новый объект DOMDocument и присваивается переменной doc.

if(!empty($this->html))
  {
      $this->doc = new DOMDocument();
      $this->_newHtmlDoc();
  }

Значит на моменте создания объекта переменная html является пустой, и в doc ничего не присваивается. А переменная html пустая из-за того что ей тоже нигде в конструкторе не присваивается значение.

READ ALSO
Не работает фильтр array_filter php

Не работает фильтр array_filter php

Хочу от фильтровать массив, где есть значения "o" но что-то неправильно делаю, что надо изменить в коде? Чтоб массив отфильтровался и сохранял...

155
Повтор php скрипта

Повтор php скрипта

Есть крон, но он может запускать скрипт не чаще чем раз в минутуТак вот как сделать так, чтобы крон запускал скрипт, а он самоповторялся 5 раз...

107
Поиск подстроки с определенным набором символов в нужном порядке

Поиск подстроки с определенным набором символов в нужном порядке

Приветствую и сразу хочу подчеркнуть, что не интересует какое-либо другое решение, кроме как одна единственная операция с помощью функции...

127
Связь андроид с онлайн базой данных

Связь андроид с онлайн базой данных

Создаю приложение на андроидНеобходимо, чтобы данные при регистрации участников сохранялись на сервере

65