Как отладить функцию move_upload_file (), когда нет явной причины сбоя? - PullRequest
0 голосов
/ 22 января 2020

TL; DR

Как мне go эффективно отладить функцию move_upload_file(), чтобы найти реальную причину ее действительных ошибок имени файла?

Как мне узнать, почему move_upload_file возвращает false, даже если он работает?

Полная история

Я работаю над функцией обновления изображения по щелчку, но move_upload_file() опускает сторону вниз.

Это функция PHP, отвечающая за загрузку:

/**
 * upload $file -> $target location
 *
 * @param $file
 * @param $target
 *
 * @return bool
 */
public function upload($file, $target)
{
    return move_uploaded_file($file['tmp_name'], $target. $file['name']);
}

Но это возвращает ложное логическое значение.

Это привело меня к изменению моей функции для целей отладки:

/**
 * upload $file -> $target location
 *
 * @param $file
 * @param $target
 *
 * @return bool
*/
public function upload($file, $target)
{
    ini_set('display_errors',1);
    ini_set('display_startup_errors',1);
    error_reporting(-1);

    var_dump($_FILES);
    var_dump($file);
    var_dump($target);
    var_dump($target. $file['name']);
    var_dump($target. $_FILES['icon']['name']);

    var_dump(move_uploaded_file($_FILES['icon']['tmp_name'], $target. $_FILES['icon']['name']));
    var_dump(move_uploaded_file($file['tmp_name'], $target. $file['name']));

    return move_uploaded_file($file['tmp_name'], $target. $file['name']);
}

Это печатает (относительно var_dump() местоположение):

$_FILES var_dump => 
array(1) {
  ["icon"]=>
  array(5) {
    ["name"]=>
    string(17) "marker_orange.png"
    ["type"]=>
    string(9) "image/png"
    ["tmp_name"]=>
    string(14) "/tmp/php59mLlb"
    ["error"]=>
    int(0)
    ["size"]=>
    int(802)
  }
}

$file var_dump =>
array(5) {
  ["name"]=>
  string(17) "marker_orange.png"
  ["type"]=>
  string(9) "image/png"
  ["tmp_name"]=>
  string(14) "/tmp/php59mLlb"
  ["error"]=>
  int(0)
  ["size"]=>
  int(802)
}

$target var_dump =>
string(81) "/var/www/dev/wordpress/wp-content/plugins/my-plugin/pub/images/dealer-icons/"

$target. $file['name'] var_dump =>
string(98) "/var/www/dev/wordpress/wp-content/plugins/my-plugin/pub/images/dealer-icons/marker_orange.png"

$target. $_FILES['icon']['name'] var_dump =>
string(98) "/var/www/dev/wordpress/wp-content/plugins/my-plugin/pub/images/dealer-icons/marker_orange.png"

move_uploaded_file (using $_FILES) => 
bool(false)

move_upload_file (using passed $file) =>
bool(false)

Из var_dump s, не похоже, что есть что-то очевидное и никакое предупреждение / ошибка не показывается. В руководстве об этом сказано по этому вопросу:

Возвращает TRUE в случае успеха.

Если имя файла не является допустимым файлом загрузки, никаких действий не произойдет, и move_uploaded_file () вернет FALSE.

Если имя файла является допустимым загружаемым файлом, но не может быть перемещен по какой-либо причине, никаких действий не произойдет, и move_uploaded_file () вернет FALSE. Кроме того, будет выдано предупреждение.

Это наводит меня на мысль, что файл не является допустимым файлом загрузки:

Эта функция проверяет чтобы убедиться, что файл, обозначенный именем файла, является допустимым файлом загрузки (это означает, что он был загружен с помощью механизма загрузки PHP HTTP POST). Если файл действителен, он будет перемещен в имя файла, заданное адресатом.

Тем не менее, использование $_FILES вместо переданного $file (идея состояла в том, чтобы передать единственное число $_FILES['key'] в функцию) по-прежнему возвращает false без предупреждения.

После чтения несколько SO сообщений, я проверил свои разрешения, но там все вроде нормально:

Correct Permissions proof

Выполнение: cd <copy path from var_dump($target)> переводит меня в правильный каталог - так что существует, принадлежит владельцу веб-сервера и имеет права доступа 755.

Затем, наконец, функция ajax отвечает за отключение функции:

//on dynamic added file input change, upload the file
$(document).on('change', '#edit_photo', function()
{
    let formData = new FormData(document.getElementById('edit_photo_form'));
    formData.append('action', 'update-photo');

    $.ajax({
        data: formData,
        type: 'post',
        url: endpoint, //endpoint = '/full/path/to/Admin.php'
        cache: false,
        contentType: false,
        processData: false,
        success: function(res)
        {
            console.log(res);
            if (res == 0) {
                alert('Error updating profile pic.. fire Trey!')
            }
        },
        error: function(res) {alert('nope');console.log(res)}
    })
});

, так что это определенно HTTP POST request:

HTTP POST proof

Doing sudo cat /var/log/apache2/error.log также вообще ничего не показывает о запросе.

Как мне go отладить move_upload_file() эффективную функцию, чтобы найти истинную причину его действительных сбоев имени файла?

Редактировать: полу-рабочее редактирование

Я редактировал свою функцию JS и HTML, чтобы форма была включена при загрузке, а нажатие на изображение устанавливает значения для существующих входных данных. в форме, которая заставила работать функцию:

//onclick image uploader/updater
$('.edit-photo').click(function()
{
    let type = $(this).attr('data-type'),
        id = $(this).attr('data-id'),
        name;

    switch(parseInt(type))
    {
        case 1: name = 'profile_pic'; break;
        case 2: name = 'cover_pic'; break;
        case 3: name = 'icon'; break
    }

    $('#edit-photo').attr('name', name);

    $('#edit-photo-form').append(
        '<input type="hidden" name="type" value="'+ type +'" />' +
        '<input type="hidden" name="id" value="'+ id +'" />'
    );

    $(document).find('#edit-photo').click();
});

$('#edit-photo').change(function()
{
    $('#edit-photo-form').submit()
});


$('#edit-photo-form').submit(function(e)
{
    e.preventDefault();

    let formData = new FormData(this);
    formData.append('action', 'update-photo');

    $.ajax({
        data: formData,
        type: 'post',
        url: endpoint,
        cache: false,
        contentType: false,
        processData: false,
        success: function(res)
        {
            console.log(res);
            if (res == 0) {
                alert('Error updating profile pic.. try again. If the problem persists, talk to Trey')
            }
        },
        error: function(res) {ajaxError(res)}
    })
});

Это фактически загружает файл, однако, move_upload_file() возвращает false, но я вижу изображение в целевой папке, так почему возвращает ложь, я изменил свою функцию следующим образом:

public function upload($file, $target)
{
    var_dump('file:'. $file['tmp_name']);
    var_dump('target:'. $target. $file['name']);
    var_dump(move_uploaded_file($file['tmp_name'], $target. $file['name']));

    return move_uploaded_file($file['tmp_name'], $target. $file['name']);
}

Это выводит:

string (19) "file: / tmp / phpv24QIy" строка (98) "target: / var / www/dev/wordpress-plugins/wp-content/plugins/my-plugin/pub/images/cover/tttt.jpeg" bool (false)

Как это может работать и возвращать false одновременно?

...