что за класс stdClass и зачем он нужен в скрипте?

Тема в разделе "PHP", создана пользователем verfaa, 7 май 2011.

Модераторы: latteo
  1. verfaa

    verfaa

    Регистр.:
    29 янв 2007
    Сообщения:
    371
    Симпатии:
    41
    Всем привет. Разбираю скрипт jQuery File Upload от blueimp.net и пытаюсь внедрить его к себе на сайт.
    В файле обработчике upload.php неоднократно используется класс stdClass который нигде в скрипте не обявлен и не описан.
    Объясните плиз, что это за класс и зачем он вообще нужен? Какой функционал он несёт в этот скрипт и почему используется именно он?(смотрел код других скриптов с похожим функционалом - там все прекрасно реализовывалось и без него).

    Далее, есть ещё несколько непонятных моментов в скрипте:

    PHP:
    $append_file is_file($file_path) && $file->size filesize($file_path);
    clearstatcache();
    120-121 линия, читаю так: если файл существует и его размер не превышает допустимые, то... непонятно чему равна переменная $append_file ?
    И для чего выполняем функцию clearstatcache() ? В нете по ней крайне мало инфы.

    и ещё:

    PHP:
    isset($_SERVER['HTTP_X_FILE_NAME']) ?
    $_SERVER['HTTP_X_FILE_NAME'] : $upload['name'],
    202 линия, что хранит переменная $_SERVER['HTTP_X_FILE_NAME'] ?
    И как правильно понимать этот кусок кода?, как сокращённую запись от
    PHP:
    if(isset($_SERVER['HTTP_X_FILE_NAME']))
    {
    $_SERVER['HTTP_X_FILE_NAME']}
    else
    {
    $upload['name']}
    ?


    Приведу тут код файла-обработчика upload.php
    Ещё было бы классно, если бы кто-нибудь откомментировал основные моменты скрипта :ah:

    PHP:
    <?php
    /*
     * jQuery File Upload Plugin PHP Example 4.2.4
     * https://github.com/blueimp/jQuery-File-Upload
     *
     * Copyright 2010, Sebastian Tschan
     * https://blueimp.net
     *
     * Licensed under the MIT license:
     * http://creativecommons.org/licenses/MIT/
     */

    error_reporting(E_ALL E_STRICT);

    $script_dir dirname(__FILE__);
    $script_dir_url dirname($_SERVER['PHP_SELF']);
    $options = array(
        
    'upload_dir' => $script_dir.'/files/',
        
    'upload_url' => $script_dir_url.'/files/',
        
    'thumbnails_dir' => $script_dir.'/thumbnails/',
        
    'thumbnails_url' => $script_dir_url.'/thumbnails/',
        
    'thumbnail_max_width' => 80,
        
    'thumbnail_max_height' => 80,
        
    'field_name' => 'file'
    );

    class 
    UploadHandler
    {
        private 
    $upload_dir;
        private 
    $upload_url;
        private 
    $thumbnails_dir;
        private 
    $thumbnails_url;
        private 
    $thumbnail_max_width;
        private 
    $thumbnail_max_height;
        private 
    $field_name;
        
        function 
    __construct($options) {
            
    $this->upload_dir $options['upload_dir'];
            
    $this->upload_url $options['upload_url'];
            
    $this->thumbnails_dir $options['thumbnails_dir'];
            
    $this->thumbnails_url $options['thumbnails_url'];
            
    $this->thumbnail_max_width $options['thumbnail_max_width'];
            
    $this->thumbnail_max_height $options['thumbnail_max_height'];
            
    $this->field_name $options['field_name'];
        }
        
        private function 
    get_file_object($file_name) {
            
    $file_path $this->upload_dir.$file_name;
            if (
    is_file($file_path) && $file_name[0] !== '.') {
                
    $file = new stdClass();
                
    $file->name $file_name;
                
    $file->size filesize($file_path);
                
    $file->url $this->upload_url.rawurlencode($file->name);
                
    $file->thumbnail is_file($this->thumbnails_dir.$file_name) ?
                    
    $this->thumbnails_url.rawurlencode($file->name) : null;
                return 
    $file;
            }
            return 
    null;
        }

        private function 
    create_thumbnail($file_name) {
            
    $file_path $this->upload_dir.$file_name;
            
    $thumbnail_path $this->thumbnails_dir.$file_name;
            list(
    $img_width$img_height) = @getimagesize($file_path);
            if (!
    $img_width || !$img_height) {
                return 
    false;
            }
            
    $scale min(
                
    $this->thumbnail_max_width $img_width,
                
    $this->thumbnail_max_height $img_height
            
    );
            if (
    $scale 1) {
                
    $scale 1;
            }
            
    $thumbnail_width $img_width $scale;
            
    $thumbnail_height $img_height $scale;
            
    $thumbnail_img = @imagecreatetruecolor($thumbnail_width$thumbnail_height);
            switch (
    strtolower(substr(strrchr($file_name'.'), 1))) {
                case 
    'jpg':
                case 
    'jpeg':
                    
    $src_img = @imagecreatefromjpeg($file_path);
                    
    $write_thumbnail 'imagejpeg';
                    break;
                case 
    'gif':
                    
    $src_img = @imagecreatefromgif($file_path);
                    
    $write_thumbnail 'imagegif';
                    break;
                case 
    'png':
                    
    $src_img = @imagecreatefrompng($file_path);
                    
    $write_thumbnail 'imagepng';
                    break;
                default:
                    
    $src_img $write_thumbnail null;
            }
            
    $success $src_img && @imagecopyresampled(
                
    $thumbnail_img,
                
    $src_img,
                
    0000,
                
    $thumbnail_width,
                
    $thumbnail_height,
                
    $img_width,
                
    $img_height
            
    ) && $write_thumbnail($thumbnail_img$thumbnail_path);
            
    // Free up memory (imagedestroy does not delete files):
            
    @imagedestroy($src_img);
            @
    imagedestroy($thumbnail_img);
            return 
    $success;
        }
        
        private function 
    handle_file_upload($uploaded_file$name$size$type$error) {
            
    $file = new stdClass();
            
    $file->name basename(stripslashes($name));
            
    $file->size intval($size);
            
    $file->type $type;
            if (!
    $error && $file->name) {
                if (
    $file->name[0] === '.') {
                    
    $file->name substr($file->name1);
                }
                
    $file_path $this->upload_dir.$file->name;
                
    $append_file is_file($file_path) && $file->size filesize($file_path);
                
    clearstatcache();
                if (
    $uploaded_file && is_uploaded_file($uploaded_file)) {
                    
    // multipart/formdata uploads (POST method uploads)
                    
    if ($append_file) {
                        
    file_put_contents(
                            
    $file_path,
                            
    fopen($uploaded_file'r'),
                            
    FILE_APPEND
                        
    );
                    } else {
                        
    move_uploaded_file($uploaded_file$file_path);
                    }
                } else {
                    
    // Non-multipart uploads (PUT method support)
                    
    file_put_contents(
                        
    $file_path,
                        
    fopen('php://input''r'),
                        
    $append_file FILE_APPEND 0
                    
    );
                }
                
    $file_size filesize($file_path);
                if (
    $file_size === $file->size) {
                    
    $file->url $this->upload_url.rawurlencode($file->name);
                    
    $file->thumbnail $this->create_thumbnail($file->name) ?
                        
    $this->thumbnails_url.rawurlencode($file->name) : null;
                }
                
    $file->size $file_size;
            } else {
                
    $file->error $error;
            }
            return 
    $file;
        }
        
        public function 
    get() {
            
    $file_name = isset($_REQUEST['file']) ?
                
    basename(stripslashes($_REQUEST['file'])) : null
            if (
    $file_name) {
                
    $info $this->get_file_object($file_name);
            } else {
                
    $info array_values(array_filter(array_map(
                    array(
    $this'get_file_object'),
                    
    scandir($this->upload_dir)
                )));
            }
            
    header('Cache-Control: no-cache, must-revalidate');
            
    header('Content-type: application/json');
            echo 
    json_encode($info);
        }
        
        public function 
    post() {
            
    $upload = isset($_FILES[$this->field_name]) ?
                
    $_FILES[$this->field_name] : array(
                    
    'tmp_name' => null,
                    
    'name' => null,
                    
    'size' => null,
                    
    'type' => null,
                    
    'error' => null
                
    );
            if (
    is_array($upload['tmp_name']) && count($upload['tmp_name']) > 1) {
                
    $info = array();
                foreach (
    $upload['tmp_name'] as $index => $value) {
                    
    $info[] = $this->handle_file_upload(
                        
    $upload['tmp_name'][$index],
                        
    $upload['name'][$index],
                        
    $upload['size'][$index],
                        
    $upload['type'][$index],
                        
    $upload['error'][$index]
                    );
                }
            } else {
                if (
    is_array($upload['tmp_name'])) {
                    
    $upload = array(
                        
    'tmp_name' => $upload['tmp_name'][0],
                        
    'name' => $upload['name'][0],
                        
    'size' => $upload['size'][0],
                        
    'type' => $upload['type'][0],
                        
    'error' => $upload['error'][0]
                    );
                }
                
    $info $this->handle_file_upload(
                    
    $upload['tmp_name'],
                    isset(
    $_SERVER['HTTP_X_FILE_NAME']) ?
                        
    $_SERVER['HTTP_X_FILE_NAME'] : $upload['name'],
                    isset(
    $_SERVER['HTTP_X_FILE_SIZE']) ?
                        
    $_SERVER['HTTP_X_FILE_SIZE'] : $upload['size'],
                    isset(
    $_SERVER['HTTP_X_FILE_TYPE']) ?
                        
    $_SERVER['HTTP_X_FILE_TYPE'] : $upload['type'],
                    
    $upload['error']
                );
            }
            if (isset(
    $_SERVER['HTTP_X_REQUESTED_WITH']) &&
                    
    $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest') {
                
    header('Content-type: application/json');
            } else {
                
    header('Content-type: text/plain');
            }
            echo 
    json_encode($info);
        }
        
        public function 
    delete() {
            
    $file_name = isset($_REQUEST['file']) ?
                
    basename(stripslashes($_REQUEST['file'])) : null;
            
    $file_path $this->upload_dir.$file_name;
            
    $thumbnail_path $this->thumbnails_dir.$file_name;
            
    $success is_file($file_path) && $file_name[0] !== '.' && unlink($file_path);
            if (
    $success && is_file($thumbnail_path)) {
                
    unlink($thumbnail_path);
            }
            
    header('Content-type: application/json');
            echo 
    json_encode($success);
        }
    }

    $upload_handler = new UploadHandler($options);

    switch (
    $_SERVER['REQUEST_METHOD']) {
        case 
    'HEAD':
        case 
    'GET':
            
    $upload_handler->get();
            break;
        case 
    'POST':
            
    $upload_handler->post();
            break;
        case 
    'DELETE':
            
    $upload_handler->delete();
            break;
        default:
            
    header('HTTP/1.0 405 Method Not Allowed');
    }
    ?>
     
  2. Alternator

    Alternator

    Регистр.:
    23 мар 2009
    Сообщения:
    295
    Симпатии:
    145
    stdClass - стандартный класс PHP
    ничего особенного в себе не несет. по сути ассоциативный массив в красивой обертке.
    часто используется там, где требуется объект, но при этом нету какого-то класса, для создания объекта.
    тогда просто создается объект класса stdClass, и ему назначется свойства.

    эти моменты прекрасно описаны в справке.
    результатом выполнения логического оператора && может быть TRUE или FALSE, в зависимости от значений операндов, в соответсвии с поведением логического И
    clearstatcache - его поведение также описано в справке. обнуляет кеш для ряда файловых операций, описанных в справке. обычно не нужен, но на некоторых ФС бывает необходим

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

    Добавлено через 57 секунд
    подвожу итог:
    RTFM
    вы не знаете самых азов, и ваши вопросы прекрасно освещаются в справочнике, несмотря на то что вы типа не можете нагуглить ответы на них
     
  3. verfaa

    verfaa

    Регистр.:
    29 янв 2007
    Сообщения:
    371
    Симпатии:
    41
    попробовал упростить файл обработчик upload.php до самого простого
    PHP:
    function post() {

    //$upload = $_FILES["upload"];
            
    if(isset($_FILES["file"])) {
                
    $upload $_FILES["file"];
            } else {
                
    $upload = array(
                    
    'tmp_name' => null,
                    
    'name' => null,
                    
    'size' => null,
                    
    'type' => null,
                    
    'error' => null
                
    );
            }

            
    // Если пользователь загрузил больше одного файла
            
    if (is_array($upload['tmp_name']) && count($upload['tmp_name']) > 1) {
                
    $info = array();
                foreach (
    $upload['tmp_name'] as $index => $value) {
                    
    $info[] = array(
                        
    'tmp_name' => $upload['tmp_name'][$index],
                        
    'name' => $upload['name'][$index],
                        
    'size' => $upload['size'][$index],
                        
    'type' => $upload['type'][$index],
                        
    'error' => $upload['error'][$index]
                    );
                    
    move_uploaded_file($upload['tmp_name'][$index], dirname(__FILE__).'/files/'.$upload['size'][$index]);
                }
            } else {
                
    // Если пользователь добавил один файл
                
    if (is_array($upload['tmp_name'])) {
                    
    $info[] = array(
                        
    'tmp_name' => $upload['tmp_name'][0],
                        
    'name' => $upload['name'][0],
                        
    'size' => $upload['size'][0],
                        
    'type' => $upload['type'][0],
                        
    'error' => $upload['error'][0]
                    );
                    
    move_uploaded_file($upload['tmp_name'][0], dirname(__FILE__).'/files/'.$upload['size'][0]);
                }
                }
            if (isset(
    $_SERVER['HTTP_X_REQUESTED_WITH']) &&
                    
    $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest') {
                
    header('Content-type: application/json');
            } else {
                
    header('Content-type: text/plain');
            }
            
    // Для отладки - смотрим что отдаёт в результате json_encode($info) в js !! Пишет nullnullnullnullnullnull
            
    $fh fopen("3.txt""a+");
            
    fwrite($fhjson_encode($info));
            
    fclose($fh);

            echo 
    json_encode($info);
    }

    post();
    Для отладки инфу, которую php отправляет обратно в скрипт я пишу ещё и в файл 3.txt, в результате при отправке через форму файлов скрипт подвисает, а в 3.txt пишет nullnullnullnullnullnull

    HTML-форма выглядит как и в оригинальном скрипте так:
    HTML:
        
    <form action="upload.php" method="POST" enctype="multipart/form-data">
            <input type="file" name="file[]" multiple>
            <button type="submit">Upload</button>
            <div class="file_upload_label">Upload files</div>
    
        </form>
    

    И ещё, ну никак не могу понять, зачем в оргинальном скрипте в классе UploadHandler метод get() ??? Ведь все файлы приходят приходят методом POST, в HTML-форме отправки файла указан method="POST". Т.е. получается метод get() вообще не должен вызываться, юзер пришёл, загрузил методом POST свои фото и пошёл далее, а в адресной строке браузера он никаких данных не передаёт и форм с методом GET на странце никаких нет, так когда и при каких действиях юзера он тогда вызывается? Объясните пожалуйста
     
  4. Miraage

    Miraage Angular/Laravel

    Регистр.:
    3 июн 2008
    Сообщения:
    230
    Симпатии:
    51
    пустой класс без свойств и методов.
    PHP:
    class stdClass {}
    например:
    PHP:
    class fooBar {}
    $object mysql_fetch_object(mysql_query("SELECT * FROM `table`"));
    print 
    get_class($object); // выводит: stdClass

    $object mysql_fetch_object(mysql_query("SELECT * FROM `table`"), 'fooBar');
    print 
    get_class($object); // выводит: fooBar