Отсутствует аргумент, хотя аргумент передан?

У меня проблемы с этим скриптом. Это скрипт загрузки изображения, и я получаю две ошибки, которые говорят об одном и том же:

Предупреждение: отсутствует аргумент 1 для DoUpload::doUpload(), который вызывается в /var/www/vhosts/mysite.net/httpdocs/mp/upload.php в строке 8 и определяется в /var/www/vhosts/mysite.net/ httpdocs/mp/includes/classes.php строка 26 Файл загружен! Предупреждение: отсутствует аргумент 1 для DoUpload::doUpload(), который вызывается в /var/www/vhosts/mysite.net/httpdocs/mp/upload.php в строке 10 и определяется в /var/www/vhosts/mysite.net/ httpdocs/mp/includes/classes.php в строке 26 Произошла ошибка при загрузке файла!

Но, как вы можете видеть в upload.php, я передаю аргумент: массив $_FILES.

Что я делаю? (Не ищу никого, кто мог бы что-то переписать, мне просто нужно небольшое руководство в том, что я делаю неправильно. :))

classes.php

<?php
error_reporting(E_ALL);
ini_set('display_errors', 'on');
require('config.php');

// Connect to database
// Does not handle anything else
class DatabaseCon {
    public $dbh;

    // Method to connect to database
    function dbConnect($config) {
        try {
            $this->dbh = new PDO("mysql:host=" . $config['host'] . ";dbname=" . $config['dbname'], $config['dbuser'], $config['dbpass']);
            $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
        } catch (PDOException $e) {
            echo $e->getMessage();
        }
    }
}

class DoUpload {
    private $target_path = 'i/';
    public $_FILES;

    public function doUpload($_FILES) {
        $this->target_path .= basename($_FILES['file']['name']);

        if (move_uploaded_file($_FILES['file']['tmp_name'], $this->target_path)) {
            echo "The file has been uploaded!";
        }
        else {
            echo "An error occurred when uploading the file!";
        }
    }

}

upload.php

<?php
ini_set('display_errors', 1);
require_once('includes/config.php');
require_once('includes/classes.php');

$db = new DatabaseCon();
$db->dbConnect($config);

$upload = new DoUpload();

$upload->doUpload($_FILES);

$sth = $db->prepare("INSERT INTO images (filename) VALUES (?)");
$sth->bindParam(1, $_FILES['file']['tmp_name']);
$sth->execute();

person Community    schedule 05.08.2012    source источник


Ответы (3)


$_FILES является суперглобальным, то есть он будет доступен для любой части вашего скрипта независимо от области действия. Вам не нужно передавать какие-либо аргументы в ваш метод doUpload, и вы по-прежнему можете использовать массив $_FILES внутри определения вашего метода.

Не знаю, из-за этого проблема или нет, но просто предупреждаю.

person Jason Fingar    schedule 05.08.2012
comment
Однако я бы серьезно посоветовал не использовать суперглобальные значения во внутренних классах. - person favoretti; 06.08.2012
comment
Какие у меня есть другие варианты, @favoretti? Я пытаюсь следовать DRY и не говорить что-то вроде $file = $_FILES['file']['tmp_name']; - person ; 06.08.2012
comment
$my_files = $_FILES; doUpload($my_files); и также переименуйте параметр doUpload() с $_FILES на что-то вроде $my_files. - person favoretti; 06.08.2012

$_FILES не всегда определяется, IIRC. Если вы ничего не загрузите или просто нажмете кнопку «Отправить» на странице, не передав никаких файлов или ничего не загрузив, это будет нулевым, что приведет к ошибке.

Кроме того, $_FILES - это суперглобальная переменная PHP, я бы не стал повторно использовать это точное имя в ваших собственных функциях (имя параметра). Не уверен, как PHP будет вести себя с этим.

Кажется, что PHP тоже советует против этого:

Примечание. Переменные-переменные Суперглобальные переменные нельзя использовать в качестве переменных-переменных внутри функций или методов класса.

Я полагаю, что использование его в качестве параметра метода подразумевает, что это переменная переменная.

person favoretti    schedule 05.08.2012
comment
Я загружаю файл. У меня есть форма, но я не думал, что это важно, поэтому я не включил ее. - person ; 06.08.2012

Сообщение об ошибке не лжет. Если указано "Отсутствует аргумент 1 для DoUpload::doUpload()", этот аргумент отсутствует.

Так, например, если переменная $_FILES не определена, вы получите эту ошибку. Однако как суперглобальный он должен быть определен - если вы не отключили загрузку файлов в конфигурации PHP.

Однако его также можно отключить, и тогда он не определяется. Так что технически может быть много причин, почему это происходит, и это требует дальнейшей отладки.

Кроме того, имейте в виду, что $_FILES является так называемым суперглобальным. Так что не называйте параметры вашей функции так (!):

    ...
    public function doUpload($_FILES) {
                             ^^^^^^^

Нет-Go. См. этот обзор документации PHP SuperglobalsDocs.

person hakre    schedule 05.08.2012
comment
Хе-хе, только что отредактировал мой пост, чтобы включить предупреждение о том, что нельзя называть параметры функции, такие как $_FILES :) - person favoretti; 06.08.2012
comment
Да ты вообще был быстрее. Мне все еще немного интересно, что происходит, когда вы это делаете, но в любом случае я не предлагаю этого делать. - person hakre; 06.08.2012
comment
То же самое и здесь, понятия не имею, как PHP отреагирует на использование суперглобальных переменных (кстати, спасибо, что помогли мне придумать правильный термин для var) во внутренних классах. - person favoretti; 06.08.2012
comment
Теперь я проверил, что $_FILES обычно доступен, если вы не отключите его в конфигурации или не отключите его. Сброс настроек работает. Для параметра функции в тот момент, когда вы передаете параметр, вы получаете значение суперглобала, так что это фактически заменяет его самим собой. - person hakre; 06.08.2012