Ответы пользователя по тегу PHP
  • Ссылки в PHP (&$var1), переменные переменых ($$var2) и их практическое применение?

    MegaMufa
    @MegaMufa
    По ссылке передаются в метод данные, которые должны быть изменены внутри метода. Иногда это избавляет от лишнего кода. Плюс расход памяти в некоторых случаях ниже.

    По поводу переменных переменных. Используются при написании обобщенного кода. Вот пример. Это поведение Yii2 для хранения деревьев в БД. Поведение - это фича фреймворка - что-то вроде трейта или миксина.

    В общем его можно подсключить к модели и она сама будет заполнять служебные поля при перемещении узлов. Для гибкости, при подключении можно указать поле таблицы, по которому надо сортировать данные. MaterializedPathBehavior::$positionAttribute. Это поле используется в коде для построения запросов:
    $position = $this->node->{$this->positionAttribute}


    Таким образом достигается гибкость. Тому, кто будет использовать это поведение не придется подгонять схему своей БД под него. Он сможет указать поля, с которыми надо работать.

    Но конечно этим надо пользоваться с осторожностью и только там, где вы точно уверенны, что это необходимо. Иначе можно наворотить неподдерживаемую кашу.

    UPD.

    Еще немного о переменных переменных. Вообще вместо них можно добавить абстрактных методов вроде getPositionAttribute() и заставить пользователя переопределить их. Это будет более правильно идеалогически. Но, используя переменные, появляется возможность настройки без написания лишних классов.
    Ответ написан
    Комментировать
  • Как обратиться к функции класса, если есть только его key?

    MegaMufa
    @MegaMufa
    Вы все правильно думаете. Только надо использовать не квадратные, а фигурные скобки.
    $a->{$func}();
    Вообще, можно и без скобочек, но с ними наглядней получается.
    $a->$func();
    И еще, у вас перед a пропущен знак $
    Ответ написан
    1 комментарий
  • Что такое абстракция для http, Request и Response в mvc framework?

    MegaMufa
    @MegaMufa
    Честно говоря первый раз слышу про этот фреймворк. Да и фреймворком это назвать сложно. Посмотрел немного исходники (это они?). Сделано, мягко говоря, через одно место. Да и ничего там практически нет. Если хотите разобраться с MVC, посковыряйте тот же Yii например.

    Касательно конкретно вашего вопроса. Response и Request используют для того, чтобы абстрагироваться от работы с потоком ввода-вывода. Response например за вас выставит необходимые заголовки. Request даст удобную обертку для доступа к $_POST и $_GET запросам. Это естестенно не все.

    Суть в том, чтобы вам не пришлось работать с низкоуровневыми штуками напрямую. Вы получаете к ним доступ через абстракцию, которая так же предоставляет кучу разных удобных плюшек. Плюс вы работаете не с глобальными данными, а с конкретным объектом, который получили в метод.

    Почему рендерит через echo - хз. В yii это например так происходит:
    public function renderPhpFile($_file_, $_params_ = [])
    {
        ob_start();
        ob_implicit_flush(false);
        extract($_params_, EXTR_OVERWRITE);
        require($_file_);
        return ob_get_clean();
    }
    Ответ написан
    4 комментария
  • ООП PHP не работает класс?

    MegaMufa
    @MegaMufa
    1. Включите вывод всех ошибок и тогда интерпретатор сам вам будет говорить, почему не работает.

    2. Вы объявляете свойства устаревшим способом. Очень-очень устаревшем (еще в 4 версии атк делали). Надо так:
    public $firstname;
    public $lastname;


    3. В конструкторе у вас неправильно обращение к переменным. Уберите второй знак доллара:
    public function __construct($firstname, $lastname) {
        $this->firstname = $firstname;
        $this->lastname = $lastname;
      }


    Должно получиться вот так:
    <?php
    class Info {
        public $firstname;
        public $lastname;
    
        public function __construct($firstname, $lastname) {
            $this->firstname = $firstname;
            $this->lastname = $lastname;
        }
    
        public function GetInfo() {
            $n = $this->firstname.' '.$this->lastname;
            return $n;
        }
    }
    
    $a = new Info('Ivan', 'Pupkin');
    echo $a->GetInfo();


    И вам надо сменить учебник, по которому вы это делаете. Он очень устарел и больше вреден, чем полезен.
    Ответ написан
    Комментировать
  • Как обращаться к константам моделей из контроллеров?

    MegaMufa
    @MegaMufa
    Я обычно использую первый вариант. В принципе во втором не вижу ничего плохого, но мне больше первый нравится. А вот третий - плохо. Зачем загрязнять глобальное пространство?

    Константы в моделях размещать нормально. Не представляю, как это может усложнить тестирование. ПО сути их можно рассматривать как обычные статичные свойства класса, но которые нельзя изменять.
    Ответ написан
    2 комментария
  • Где правильнее проверять пользовательские данные? В контроллере или модели?

    MegaMufa
    @MegaMufa
    Я считаю, что "толстая модель, тонкий контроллер" - это самый подходящий вариант.
    Вся логика приложения должна содержаться в моделях. Модель - это не просто сущности из бд, это еще и инкапсулированая логика ее обработки. А контроллер должен говорить модели, что делать и рендерить вьюхи.

    Например этот кусок кода неправильный:
    class MyController
    {
        public function myAction()
        {
            $user = new User();
            $user->load($_POST);
            if ($user->valiadate()) {
                $user->saveToDatabase();
            } else {
                throw new Exception("...");
            }
        }
    }

    Неправильный потому что контроллер знает, как модель сохраняет данные. Что сначала идет валидация, а потом сохранение в бд. И если вы потом решите не проводить валидацию, или добавить еще один проверяющий метод (например), то вам придется делать это везде.

    Правильно быдет так: в модели определеить метод, содержащий логику:
    class User
    {
        public static function create(array $data)
        {
            $record= new static;
            $record->load($data);
            if($record->validate()){
                $record->saveToDatabase();
            } else {
                throw new Exception("...");
            }
            
            return $record;
        }
    }


    А в контроллере просто дергать его и передавать туда данные:
    class MyController
    {
        public function myAction()
        {
            $user = User::create($_POST);
        }
    }


    Таким образом все логика работы модели (в том числе валидация) инкапсулирована снутри класса, и другие классы не знают, как это происходит.

    Такой подход облегчает сопровождение кода а так же облегчает написание тестов.
    Ответ написан
  • Есть ли ошибки которые зависят от платформы?

    MegaMufa
    @MegaMufa
    Например, если вы в полных именах директорий будете использовать виндовый разделитель "\", на линуксе не заработает. Там надо "/" писать. А вот наоборот все сработает. Но по хорошему надо DIRECTORY_SEPARATOR использовать.
    Ответ написан
    Комментировать
  • Как грамотно закрыть MySQLi?

    MegaMufa
    @MegaMufa
    Соединение закроется автоматически, когда отработает скрипт. В дальнейшем вам возможно еще раз понадобиться обращатся к бд. А установление соединения - довольно дорогостоящая операция.

    Если вы пишите на php и это не демон (написание которого на пыхе - сомнительное удовольствие), то об освобождении ресурсов сильно не парьтесь. Скрипт отработал - за вас все подчистят.

    Конкретно в этом случае, вынесите закрытие соединения в дестурктор. Или создайте отдельный метод close() и дергайте его.

    По поводу подхода. В данном случае действительно будет лучше писать в процедурном стиле (и в этом нет ничего плохого; ООП - не панацея). Здесь вы класс используете не по назначению. Классы нужны для разделения логики: один отвечает за соединение с бд, другой за формирование запросов, третий за формирование результатов.

    Я не хочу вас обидеть, но вы действительно не понимаете самого смысла ООП. И просто на голой теории это сложно понять. Я сам два года писал, используя ООП. И только потом понял для чего это на самом деле надо.

    Для поднятия навыка попробуйте покопаться в исходниках какого-нибудь фреймворка. Я в свое время перебрал ядро Yii. Он прост для понимания и не перегружен паттернами.

    Касательно конкретно этого случая, я уже сказал, вынесите закрытие соединения в деструктор.
    Ответ написан
    Комментировать
  • Позднее статическое связывание php: как это работает?

    MegaMufa
    @MegaMufa
    Смотрите. Есть такая простая иерархия классов:
    class A
    {
        public static $text = 'class A';
    
        public function selfTest()
        {
            echo self::$text;
        }
    
        public function staticTest()
        {
            echo static::$text;
        }
    }
    
    class B extends A
    {
        public static $text = 'class B';
    }


    Мы создаем экземпляк субкласа и вызываем методы, определенные в предке.
    $obj = new B();
    $obj->selfTest(); // выведет "class A"
    $obj->staticTest(); // выведет "class B"

    self всегда указывает на тот класс, в котором он написал. Здесь метод описан в классе A, и self указывает на класс A, хоть и вызывается из класса B.
    Значение static вычисляется при вызове. И static указывает на класс объекта в котором произошел вызов. В нашем случае он указывает на B, хотя сам код описан в классе A.

    Зачем это надо? Для того, что бы можно было переопределять статичные члены вашего класса в наследниках и вы могли обращаться к новым значениям из методов, описанных в предке.

    С обычными не статичными членами это и так работает, потому что они собираются, когда вы создаете объект класса. Что бы это работало для статичных методов, надо использовать static
    Ответ написан
    1 комментарий
  • PHP: как сделать автоматическое добавление записей на стену сообщества вконтакте?

    MegaMufa
    @MegaMufa Автор вопроса
    Все оказалось до банального просто. Делать запрос через curl и сохранять куки, которые выдает сервер. Тогда все работает.
    Ответ написан
    1 комментарий
  • Как получить ширину и высоту изображения, хранящегося на сервере?

    MegaMufa
    @MegaMufa
    getimagesize() В возвращаемых данных есть размеры изображения. В примерах кода (внизу страницы) есть вывод этих данных прям в тег img
    list($width, $height, $type, $attr) = getimagesize("img/flag.jpg");
    echo "<img src=\"img/flag.jpg\" $attr alt=\"getimagesize() example\" />";
    Ответ написан
    Комментировать
  • CMS с простым шаблонизатором

    MegaMufa
    @MegaMufa
    Судя по требованиям, вордпресс вам отлично подойдет.
    Ответ написан
    Комментировать
  • Существуют ли продвинутые php-курсы на русском языке?

    MegaMufa
    @MegaMufa
    https://github.com/yiisoft/yii2

    В свое время в отделе, в котором я работал, нужно было написать небольшой фреймворк для специфичных задач так как существующие не были сильно избыточны. Это дело поручили мне, а с пыхом я был знаком только по слухам. Хотя раньше шпилил на др языках.

    Для того что бы "проникнуться" духом пыхыпы перелопатил половину исходников этого фреймворка (правда тогда это была первая версия). Понял очень многое: как строятся сложные системы на пыхе, как в нем патерны применять, какие есть хаки и фичи в языке.

    Это муторно и скучно, но, поверьте, оно того стоит.

    А без английского языка выше джуниора подняться не получиться. Актуальная информация только на оргинале. НА русский переводят уже устаревшую.
    Ответ написан
    Комментировать
  • Как спроектировать архитектуру простого форума на PHP?

    MegaMufa
    @MegaMufa
    Простите, это вам при устройстве на работу такое тестовое задание дали?
    Ответ написан
    1 комментарий
  • php vs python vs ruby(ror)

    MegaMufa
    @MegaMufa
    А может вообще pascal, раз его в школе учили?

    Извините, не удержался.
    Вопрос, хоть и поднадоевший, но я вас понимаю. Сам в свое время задавался им. Сначала я учил php, т.к. когда начинал учиться про руби и питон даже не слышал. А вот потом задался вопросом, может стоит сменить язык. Тоже выбирал между питоном и руби. И знаете что? Остался на php.

    Попробовал обе альтернативы и обе мне понравились больше, чем php. Но различия не были настолько весомыми, что бы переучиваться.

    Чисто эстетически, мне php очень не нравиться из-за местами "неожиданного интерфейся". (Например: В некоторых схожих функциях параметры в разном порядке). Зато есть куча замечательных ферймворков. К примеру Yii - использую и php не вызывает такого отвращения.

    В питоне мне понравилась "компиляция" в байт код. Плюс на нем пишут приложения и для десктопа, чего на ПЫХЫПЫ не сделаешь.

    Но если бы я сейчас выбирал, что учить - то выбрал бы руби.
    Очень развитая экосистема (ror, sass, coffee, HAML). Они под себя все окружение подгоняют. Плюс, язык чисто ООП-шный, что мне очень понравилось. Красивый он, синтаксис мне больше, чем у питона понравился.

    Не буду давать банальный совет, попробовать все и выбрать. Знаю, что не сделаете так. Но почитайте туториалы, посмотрите синтаксис. И выбирайте тот, на котором вам будет приятнее писать. Как по мне, это единственное весомое различие.

    Синтаксис можно сравнить здесь:
    hyperpolyglot.org/scripting
    hyperpolyglot.org/scripting2

    А вот тут таблица, сравнения разных языков (не только этих):ru.wikipedia.org/wiki/%D0%A1%D1%80%D0%B0%D0%B2%D0%...
    Ответ написан
    3 комментария
  • Почему медленно грузится статика?

    MegaMufa
    @MegaMufa Автор вопроса
    Хм. Судя по всему, @alekciy был прав. Тормоза сами прошли. Сейчас те же файлы грузятся за 200-300мс, что вполне приемлемо.
    Ответ написан
    Комментировать
  • Как организовать вход в админку сайта администратору?

    MegaMufa
    @MegaMufa
    Если админ - конкретный человек, и меняется он не так часто, делаю вход в админку по адресу admin.site.com. Но сам домен в DNS не прописываю. Записываю его в файле host. И все, на данный поддомен попадет только админ. Ну или тот, кто знает об этой фиче, но там форма авторизации.
    Ответ написан
    Комментировать