Форум SAPE.RU

Форум SAPE.RU (http://forum.sape.ru/index.php)
-   Ошибки при работе с системой (http://forum.sape.ru/forumdisplay.php?f=14)
-   -   Warning: array_key_exists() (http://forum.sape.ru/showthread.php?t=32426)

suraev 04.06.2009 22:03

Warning: array_key_exists()
 
Warning: array_key_exists() [function.array-key-exists]: The second argument should be either an array or an object in /home/itbelarus/www/it-belarus.net/[hash]/sape.php on line 395

Площадка it-belarus.net

Два дня (вчера и сегодня) постоянно вылазит такая ошибка. По форуму я посмотрел - не докачивается файл. В течение дня несколько раз удалял файл, он по-прежнему не докачивается. Причём несколько раз проверил, скачивается только 224 килобайта (должно быть около 1.5 мегабайта). В чём может быть проблема? До этого больше года проблем почти никогда не было, а тут уже более суток проблема.

Последний Герой 04.06.2009 22:05

suraev, хеш зря спалили, ибо догадываюсь на папке 777 стоит

просто удалите линкс.дб и все путем станет

suraev 04.06.2009 22:07

Цитата:

Сообщение от Последний Герой (Сообщение 467971)
suraev, хеш зря спалили, ибо догадываюсь на папке 777 стоит

просто удалите линкс.дб и все путем станет

Спасибо, убрал хэш.

В том-то и дело, удалял раз 10 уже.

Последний Герой 04.06.2009 22:10

Цитата:

Сообщение от suraev (Сообщение 467973)
В том-то и дело, удалял раз 10 уже.

в саппорт к хостингу обратитесь
возможно 2 проблемы:
1) проблема сети
2) в php.ini стоит ограничение времени выполнения - скрипт убивается до того, как выкачается файл с диспенсера сапе

suraev 07.06.2009 16:58

Вступил в переписку с хостером.

---
Добрый день, вчера (4 июня) и сегодня (5 июня) у сайта it-belarus.net проблема со скачкой файла с серверов dispenser-01.sape.ru и dispenser-02.sape.ru. Файл докачивается не полностью (вместо 1.5 мегабайта мы получаем от 200 килобайт до 1 мегабайт). Пробовали неоднократно.

Там подсказывают, что это может быть связано с лимитом времени на исполнение скрипта. Может быть, вы меняли какие-то настройки вчера?
---

Ответ:

---
Мы ничего не меняли. Есть прямая ссылка для проверки скорости скачивания?
---

Вопрос - какой url им сообщить для проверки?

Ank 07.06.2009 19:18

suraev, поиск по слову dispenser даст ссылку на поолучение линкса. ее и отдайте хостеру.

Avelon 07.06.2009 19:20

кинул в личку урл

Добавлено через 1 минуту
можно попробовать поменять вид соединения

http://www.sape.ru/faq.php?q_id=229

Последний Герой 07.06.2009 19:34

Цитата:

Сообщение от Avelon (Сообщение 470163)
можно попробовать поменять вид соединения

разница? в любом случае все соединения в конечном счете идут через сокеты. скрипт закачки написанный на PHP будет выполнятся медленнее чем file_get_contents а значит и на загрузку понадобится чуть больше времени.

suraev 09.06.2009 19:02

Спасибо за участие.

Хостер что-то подкрутил после получения ссылки на файл и всё стало пучком.

2mik 09.06.2009 20:00

Вложений: 1
Поразбирался немного с проблемой неполного линкса, так как советы которые нашел не очень-то помогали. ИМХО проблемы с сетью тут не при чем, ошибка происходит непосредственно при записи уже закаченной информации в файл. В скрипте sape.php пред записью стоит проверка на корректность закаченных данных. То есть недокаченный линкс даже не начнет записываться.
Из-за косяка в sape.php, если при записи произойдет ошибка, скрипт продолжит выполняться, как будто все нормально, в обработку поступит обрезанный линкс, и получаем Warning: array_key_exists()... Более того, при следующем запуске sape.php получим то же самое и так будет, пока линкс не обновится и не запишется полностью.

Решение 1.
Сначала я добавил проверку на корректность линкса при каждом запуске sape.php. Если есть ошибки, то линкс загружался заново.

PHP код:

    function load_data() {
        
$this->_db_file $this->_get_db_file();

        if (!
is_file($this->_db_file)) {
            
// Пытаемся создать файл.
            
if (@touch($this->_db_file)) {
                @
chmod($this->_db_file0666);    // Права доступа
            
} else {
                return 
$this->raise_error('Нет файла ' $this->_db_file '. Создать не удалось. Выставите права 777 на папку.');
            }
        }

        if (!
is_writable($this->_db_file)) {
            return 
$this->raise_error('Нет доступа на запись к файлу: ' $this->_db_file '! Выставите права 777 на папку.');
        }

        @
clearstatcache();
//В следующих двух стоках считывание и проверка на корректность файла
        
$data $this->_read($this->_db_file);       
        if (
filemtime($this->_db_file) < (time()-$this->_cache_lifetime) || filesize($this->_db_file) == || (@unserialize($data) == false)) {

            
// Чтобы не повесить площадку клиента и чтобы не было одновременных запросов
            
@touch($this->_db_file, (time() - $this->_cache_lifetime $this->_cache_reloadtime));

            
$path $this->_get_dispenser_path();
            if (
strlen($this->_charset)) {
                
$path .= '&charset=' $this->_charset;
            }

            foreach (
$this->_server_list as $i => $server){
                if (
$data $this->fetch_remote_file($server$path)) {
                    if (
substr($data012) == 'FATAL ERROR:') {
                        
$this->raise_error($data);
                    } else {
                        
// [псевдо]проверка целостности:
                        
if ((@unserialize($data) != false) && (substr($data,strlen($data)-2,2)=="}}")) {
                            
$this->_write($this->_db_file$data);
                            
                            break;
                        }
                    }
                }
            }
        }

        
// Убиваем PHPSESSID
        
if (strlen(session_id())) {
            
$session session_name() . '=' session_id();
            
$this->_request_uri str_replace(array('?'.$session,'&'.$session), ''$this->_request_uri);
        }
        
$this->set_data(@unserialize($data));

    }




Решение 2
Предыдущее решение вобщем-то работало, но хотелось выяснить почему появлялись ошибки записи. Покопался в коде и в и-нете. Оказалось, что функция записи в файл в sape.php написана довольно стандартно через блокировку файла. При таком подходе при ограничении ресурсов и большом количестве попыток блокировать файл разными процессами php отрабатывает криво и файл часто записывается урезанным. Однако, применив небольшую хитрость с дополнительными блокировочным и временным файлами можно полностью устранить ошибки записи даже на самых тормозных хостингах. Код переписанной функции:
PHP код:

    function _write($filename$data) {
        
        
$lock fopen($filename.".lock","a");   
        if(
flock($lockLOCK_EX)) {
            
$tmp=fopen($filename.".tmp","w");     
            @
fwrite($tmp$data);
            
fclose($tmp);
            
unlink($filename);                              
            
rename($filename.".tmp"$filename);           
            
flock($lockLOCK_UN);
            
fclose($lock);
        
             if (
md5($this->_read($filename)) != md5($data)) {
                return 
$this->raise_error('Нарушена целостность данных при записи в файл: ' $filename);
            }

            return 
true;
        }

        return 
$this->raise_error('Не могу записать данные в файл: ' $filename);
    } 

У меня на двух разных хостингах прекрасно работали как первое решение, так и второе, а также оба вместе. Все же рекомендую использовать только второе, т.к. в случае других проблем с записью в файл (права доступа, закончилось место и др.), ошибок не будет, но каждый раз линкс будет скачиваться с диспенсеров сапы (пожалейте их серверы :) ).

Прикладываю скрипт со вторым решением.


Часовой пояс GMT +3, время: 22:17.

Работает на vBulletin® версия 3.8.7.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
SAPE.RU — система купли-продажи ссылок с главных и внутренних страниц сайтов.