• PHP. Почему увеличивается пиковое значение используемой памяти при очистке переменных и массивов?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    Не очень понятно, почему при удалении массивов и переменных пиковое использование памяти скриптом растёт.


    Потому что unset не удаляет ничего, а добавляет в zval новые данные - флаг удаления, для того, чтобы GC смог подчистить их при следующем запуске (Хотя это тоже не так, GC в пыхе почти ничего не подчищает, а просто перезаписывает поверх, т.к. аллокации памяти требуют времени).

    А сама операция unset нужна лишь для того, чтобы корректно убирать данные в реалтайм (т.е. грубо говоря while true) приложениях, если нет уверенности в том, что refcount после отработки кода у zval будет равен 0. Если же в приложении нет никакого эвентлупа, то использование unset и gc_collect_cycles будет лишь добавлять тормозов и пиков потребления памяти.

    Это не абсолютная истина, конечно. Но лучше доверить менеджмент памяти именно PHP. Но например, в приведённом выше коде, который устарел лет на 10 и сейчас просто не будет работать - после последней строчки не останется вообще никаких переменных в памяти. Точнее они останутся, но с refcount = 0, а значит создание новой переменной просто перезапишет уже выделенную память.
    Ответ написан
    3 комментария
  • Как правильно сделать пост на стене группы при помощи Вконтакте API wall.post?

    zorca
    @zorca
    Рабочий вариант:
    <?php
    CONST TOKEN = '?:%*?:%*?:%*?:%*?:%*';
    $user_id = 666;
    $text = 'Постим на страничку от имени Steelcat';
    $image_name = 'steelcat.jpg';
    $image = __DIR__ . DIRECTORY_SEPARATOR . $image_name;
    $upload_url = vkAPI('photos.getWallUploadServer', ['owner_id' => $user_id])->response->upload_url;
    try {
        $ch = curl_init($upload_url);
        $cfile = curl_file_create($image, mime_content_type($image), $image_name);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, ['photo' => $cfile]);
        $responseUpload = json_decode(curl_exec($ch));
        curl_close($ch);
        echo 'Картинка успешно загружена<br>';
    } catch (Exception $e) {
        exit('Неизвестная ошибка при попытке загрузки картинки');
    }
    $responseSave = vkAPI('photos.saveWallPhoto', [
        'owner_id' => $user_id,
        'photo' => stripslashes($responseUpload->photo),
        'server' => $responseUpload->server,
        'hash' => $responseUpload->hash,
    ]);
    if ($responseSave->error) {
        exit('Неизвестная ошибка при попытке сохранения картинки');
    } else {
        echo 'Картинка успешно сохранена<br>';
    }
    $responsePost = vkAPI('wall.post', [
        'owner_id' => $user_id,
        'message' => $text,
        'attachments' => $responseSave->response[0]->id,
        'hash' => $responseSave->response[0]->hash,
    ]);
    if ($responsePost->error) {
        if ($responsePost->error->error_code == 214) {
            exit('Стена закрыта для постинга');
        } else {
            exit('Неизвестная ошибка при попытке постинга');
        }
    } else {
        echo 'Пост успешно добавлен';
    }
    function vkAPI($method, array $data = [])
    {
        $params = [];
        foreach ($data as $name => $val) {
            $params[$name] = $val;
            $params['access_token'] = TOKEN;
        }
        $json = file_get_contents('https://api.vk.com/method/' . $method . '?' . http_build_query($params));
        return json_decode($json);
    }
    Ответ написан
    9 комментариев