Задать вопрос
  • Почему при запросе к REST Yii2 методом DELETE выдаётся ошибка 403?

    @PiloTeZ Автор вопроса
    ...
    Долго искал ответ, в итоге нашел его в конфигурации апача
    Решение: прописать в htaccess код
    <LimitExcept GET POST HEAD DELETE PUT>
        Require all denied
    </LimitExcept>

    Администратор серверов из меня никакой, поэтому на сколько это безопасно и правильно не скажу
    Ответ написан
    Комментировать
  • Как вылечить сервер, который считает, что все место на диске закончилось, так как df -h показывает 100% занятого места на /, но df -ih показывает 27%?

    ZloyHobbit
    @ZloyHobbit
    Достаточно классический случай, процесс держит удаленный файл, место не очищается, но и файла уже нет.
    Ищется так: lsof -nP | grep '(deleted)'
    Лечится убиением процесса, или прочисткой proc файла.
    Вот есть обсуждение на стаке.
    Ответ написан
    Комментировать
  • Какие книги почитать на тему социальной инженерии?

    XXX
    @XXX
    Решение где-то рядом
    @dusty_arrow по теме соц инженерии на хабре есть дельные статьи(и комменты!), получше многих книг будут!
    Теория:
    Социальная инженерия: ликбез про метод атаки, кото...
    Методы социальной инженерии, используемые для расп...

    Практика:
    Социальная инженерия в Facebook и не только. Разбо...
    Социальная инженерия vs mchost.ru
    Социальная инженерия на практике: «физический дост...
    Социальная инженерия: «Дорожное яблоко»

    Голова! Работа мозга! Поиск и анализ информации! Без этого толку от книжек про соц инженерию будет ноль. Учитесь искать и думать самостоятельно!
    Ответ написан
    Комментировать
  • Как синглтон превратить в DI в Yii2?

    Decadal
    @Decadal
    А зачем вам делать его DI, сделайте его компонентом. Extends Component, а в конфигурации components=> [
    'api'=> [ 'class' => 'namespace\вашего\клаccа']
    ]
    Обращаться к нему так: Yii::$app->api.
    Если что-то не понятно, спросите в комментарии, напишу развернуто.
    Ответ написан
    Комментировать
  • PSR-0 или PSR-4, и как правильно построить структуру проекта?

    27cm
    @27cm
    TODO: Написать статус
    Первый вопрос который меня интересует это PSR-0 или PSR-4. На сколько я понял по состоянию на 21 октября 2014 года PSR-0 был помечен как устаревший.

    PSR-4 не замена PSR-0, а дополнением к нему.
    github.com/php-fig/fig-standards/blob/master/accep...


    про PSR-3 я вообще как-то не нашел русскоязычной информации, словно такого стандарта нет

    Видать, не перевели. Читайте в оригинале:
    github.com/php-fig/fig-standards/blob/master/accep...


    /path/to/project/ это путь к проекту и данный путь нигде не фигурирует, это та директория из которой запускается основной index.php

    Да, это пусть к PHP файлам проекта. Но index.php обычно выносят в отдельный каталог (например, /public), а все классы проекта хранятся, например, в /src (или /lib или ещё как угодно). В конфигурации веб-сервера запрещают отправлять запросы к любым файлам, не лежащим в /public, благодаря этому /public/index.php является единственной точкой входа для внешних запросов.


    ./vendor это папка назначение которой я не понимаю

    Это папка для сторонних библиотек, используемых в вашем проекте. Используется composer'ом. Внутрь лезть особо причин нет, composer сам решит как ему там всё разложить. Свои классы вы туда тоже не должны писать.


    в итоге честно говоря я запутался в том как правильно надо строить свои каталоги, какие папки обязательные какие нет, когда использовать src, когда lib, когда tests, почему в некоторых структурах приходится дважды указывать имя поставщика и имя пкета и т.д.

    src и lib - скажем так, синонимы. Кому как больше нравится. Главное, что внутри лежат сами PHP файлы проекта, следующие стандарту PSR-4. Лежат там только файлы, написанные авторами проекта. Поэтому нет смысла класть vendor внутрь src (или lib).
    test - каталог для тестов проекта.
    В папке vendor имя поставщика и имя проекта могут совпадать, вот они и дублируются.

    Так как вы изобретаете свой велосипед, то и структуру каталогов делайте свою, или посмотрите на популярные CMS/фреймворки, но везде будет по-разному. Joomla, WordPress, Yii, Zend Framework, Symfony.

    Я придерживаюсь такой структуры:
    /config                     Глобальные настройки проекта.
    /data                       Временные файлы. Например:
    /data/cache	            Файлы кеша.
    /data/logs	            Логи.
    /data/tmp	            Прочие временные файлы.
    /module                     Модули проекта. Например:
    /module/Backend	        
    /module/Backend/config      Настройки модуля.
    /module/Backend/src	    Файлы PHP модуля. Например:
    /module/Backend/src/Backend/Path/To/ExampleClass.php
    /module/Backend/test	    Unit-тесты модуля.
    /module/Backend/view	    Шаблоны модуля.
    /module/Frontend/...
    /public/index.php
    /public/css
    /public/font
    /public/img
    /public/js
    /vendor


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

    opium
    @opium
    Просто люблю качественно работать
    Плеск и цпанель это вообще не про деплоймент
    В них есть инструмент миграции сайтов и юзеров , все делается в несколько команд
    Ответ написан
    1 комментарий
  • Существует ли готовое решение для переноса нескольких десятков сайтов на другой сервер?

    @AtaZ
    кто знает, тот поймет
    Если сайты создавали не вы, не вы держатель обоих хостингов, то об автоматизации можно забыть просто под страхом смерти. Уж не знаю каким уровнем доступа вы располагаете, но с произвольным набором хостингов даже ручные велосипеды не слишком безопасны.

    В случае когда всё своё или хотя одна половина своя, то строгайте велосипед. Чего-то конкретного и не посоветуешь тут, на мой взгляд любой проект старше года индивидуален во всём.
    Ответ написан
    Комментировать
  • Существует ли готовое решение для переноса нескольких десятков сайтов на другой сервер?

    inoise
    @inoise
    Solution Architect, AWS Certified, Serverless
    Рекомендую освоить Ansible и автоматическое развертывание. Если вам требуется без остановки работы и есть постоянная запись в БД то с репликацией и другими плясками с бубном. Автоматизировать тут - зло
    Ответ написан
    Комментировать
  • Существует ли готовое решение для переноса нескольких десятков сайтов на другой сервер?

    Sanes
    @Sanes
    Нет конечно. Это частный случай.

    устал таскать сайты клиентов вручную

    Чтобы не таскать вручную, пользуйтесь панелью управления, например ISPmanager. Или пишите свой велосипед, если заняться нечем.

    p.s. Смотрите в сторону систем управления конфигурациями. Самый простой Ansible.
    Мой старенький велосипед для LEMP. Если нужен + Apache mpm_itk, пишите, поделюсь.
    Ответ написан
    Комментировать
  • Как правильно организовать инфраструктуру продакшена и процессы разработки, тестирования и деплоя?

    Так, система управлениями версиями у вас есть, теперь посмотрите на автотесты, юнит тесты, прочие системы автоматизированного тестирования, затем на системы хранения версий\отдельных библиотек , затем на системы управления серверами и ПО на них, системы мониторинга, а так же та то, как это всё связать, дополнительно можно посмотреть в сторону devOps

    Если рассматривать сферического коня в вакууме, то примерно так:
    разработчик делает коммит в git -> git c помощью хуков проверяет синтаксис ( если это код), еще что-либо, если все окей, то коммит проходит -> некая система типа jenkins\bamboo\etc видит новый коммит, разворачивает новый поделку, затем прогоняет юнит\смоук\прочие автотесты -> если тесты не прошли, то создаёт тикет в баг трекере , если тесты прошли - проставляет метку\версию , возможно заливает результат в некий репозиторий, либо в какую-нибудь хранилку ( типа artifactory ) -> система управления серверами ( либо в ручном режиме админ ) обновляет сервера -> по окончанию - неплохо бы проверить, что покажет мониторинг и отправить письмо радости менеджеру проекта.

    Как-то так, но опять же , это конь в вакууме в идеальном мире. А еще можно книжки разные почитать =)

    UPD: а еще вот хороший статья - habrahabr.ru/post/197026
    Ответ написан
    4 комментария
  • Как убрать небезопасный домен cobalten[.]com?

    azerphoenix
    @azerphoenix
    Java Software Engineer
    Здравствуйте!
    1) установите плагин Wordfence и просканируйте сайт. Обычно он находит лишние ссылки.
    2) Не факт, что вы найдете при массовом поиске через notapad++ название cobalten, так как они обычно закодированы в base64 например...
    3) на первый взгляд ничего подозрительного не заметил... Рекомендую вам еще заказать оптимизацию сайта... а то главная весит 15 мб, а кол-во запросов более 200)))
    Ответ написан
    1 комментарий
  • Легаси-монстр. Как побеждаете?

    @RidgeA
    Немного банальностей:
    1. Бизнес не даст ресурсов на переписывание проекта с 0: время и большие риски
    2. Бизнесу как правило все-равно какое говно там крутится, лишь бы деньги приносило.
    3. Если более-менее адекватное руководство - нужно донести идею постепенного рефакторинга кода по мере необходимости в процессе фикса багов и разработки новых фич и тем самым аргументировать что на разработку новых фич/фикс багов нужно больше времени.

    Как я бы делал:
    1. Тесты на существующие функции (если возможно, видел методы в контроллерах с мешаниной вызовов методов моделей, созданием DTO и сохранением их через репозиторий, прямых http-запросов и запросов в бд на 1000+ строк, покрыть такое тестами - невозможно)
    2. Составить план рефакторинга, где отметить что и где надо сделать, коротко, в основном для команды разработчиков.
    3. Постепенно рефакторить старый код по мере взаимодействия с ним.
    4. Новый код - писать сразу правильно, для взаимодействия со старым кодом где нет возможности/времени его переделать - делать какие-то адаптеры, что бы не распространять токсичный код.
    5. Как оперативная мера защиты от SQL иньекций можно поставить что-то вроде этого https://github.com/nbs-system/naxsi
    6. Мониторинг кода, который не используется - pinba.org , по мере обнаружения такого кода - удалять безвозвратно (в крайнем случае есть VCS, я надеюсь). Начать с более высокоуровнего кода - контроллеры, напримерю. Плюс IDE в этом могут помочь и grep.
    7. Как вариант - новые фичи можно пилить в отдельном проекте (v2), крутить оба и постепенно переходить на новый, со временем старый (v1) выкинуть (и начать делать новый - v3 :-) )
    Ответ написан
    3 комментария
  • Клиент много задает вопросов, как быть?

    podust
    @podust
    Вести повременную тарификацию работы и общения с клиентом. Если клиенту это не понравится и он отпадет — тогда и к лучшему, ибо себе дороже тратить свое время (которое, как известно, = деньги).
    Ответ написан
    2 комментария
  • Книги на Github?

    DDDsa
    @DDDsa
    За компанию скину ссылку на тему со списочком книг, "которые должен прочитать каждый программист".
    Ответ написан
    3 комментария
  • Чем чревато заключение NDA?

    noby2000
    @noby2000
    Founder.
    1) ничем не чревато. NDA подписывается с целью общаться с Вами спокойно и открыто, в том числе с конфиденциальной информацией. В западных юрисдикциях более распостранено. Да, NDA подписывается и перед собеседованием, и это не означает, что тебя возьмут на работу. Лично я считаю, что любое обсуждение деталей проекта должно начинаться с NDA.
    2) паспортные данные Ваши нужны для Вашей идентификации. Вас не смущает, что покупая машину, квартиру, приходя к нотариусу, заказывая авиабилет, устраиваясь на работу, заключая любой другой договор, давая расписку, Вы указываете паспортные данные? Правда, волноваться не о чем...
    3) А вот Вашей большой ошибкой будет не подписать договор найма, авторского заказа или иным образом не урегулировать ваши трудовые отношения. Не забыть там указать момент перехода авторских прав на разработку к заказчику (например, момент оплаты). Вот тут-то и кроется загвоздка: работая без договора но с NDA, Ваш код может являтся ИХ коммерческой тайной независимо от оплаты.
    Ответ написан
  • Как создать бота WhatsApp?

    DmitriyEntelis
    @DmitriyEntelis
    Думаю за деньги
    https://github.com/search?utf8=%E2%9C%93&q=whatsapp+php
    Берете любой репозиторий и вперед
    Ответ написан
    2 комментария
  • Где арендовать вычислительные мощности под одну задачу?

    @BrainHacker
    Присмотритесь к Amazon EC2. К примеру, их GPU cluster имеет два процессора Intel Xeon X5570 3.00GHz, каждый содержит 8 ядер. Стоимость за час аренды: $2.10 для Linux, $2.60 для Windows.
    У них есть CPU cluster. По заверениям, там должно быть в 2 раза больше CPU.
    Ответ написан
  • Python IDE

    @switlle
    www.jetbrains.com/pycharm/

    По-моему что-то луче чем JetBrains найти будет тяжело. Вы для начала попробуйте — потом купите когда будет очередная волна скидок. Уверяю Вас покупать будете с великолепным чувства радости!
    Ответ написан
    1 комментарий
  • YII2 gridview filter?

    @DoNetSSS Автор вопроса
    Извините за мой код ведь я только учусь.
    Вот как надо было сделать.

    Контролер
    public function actionIndex($nav = null)
        {
            $departments = Departments::getAll();
            $searchModel = new Payments();
            $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
            return $this->render('index', [
                'departments' => $departments,
                'dataProvider' => $dataProvider,
                'searchModel' => $searchModel,
            ]);
        }


    Модель
    class Payments extends ActiveRecord
    {
        public $nameDepartments;
        public $nameExpenses;
    
        public function rules()
        {
            return [
                [['nameDepartments', 'nameExpenses', 'type', 'price', 'date', 'name'], 'safe'],
            ];
        }
    
        public function search($params, $where = null)
        {
            $query = Payments::find()->leftJoin(Expenses::tableName(), 'expenses.id = payments.idexpense')->leftJoin(Departments::tableName(), 'expenses.iddepartment = departments.id')->where($where);
            $dataProvider = new ActiveDataProvider([
                'query' => $query,
                'pagination' => [
                    'pagesize' => 20,
                ],
                'sort' => [
                    'attributes' => ['name', 'type', 'price', 'date',
                        'nameDepartments' => [
                            'asc' => ['departments.name' => SORT_ASC],
                            'desc' => ['departments.name' => SORT_DESC],
                        ],
                        'nameExpenses' => [
                            'asc' => ['expenses.name' => SORT_ASC],
                            'desc' => ['expenses.name' => SORT_DESC],
                        ],
                    ],
                ],
            ]);
    
            $this->load($params);
    
            if (!$this->validate()) {
                return $dataProvider;
            }
    
            $query->andFilterWhere([
                'id' => $this->id,
                'type' => $this->type,
                'price' => $this->price,
                'date' => $this->date,
            ]);
    
            $query->andFilterWhere(['like', 'payments.name', $this->name]);
            $query->andFilterWhere(['like', 'departments.name', $this->nameDepartments]);
            $query->andFilterWhere(['like', 'expenses.name', $this->nameExpenses]);
    
            return $dataProvider;
        }
    
        public function attributeLabels()
        {
            return array(
                'date' => 'Дата',
                'type' => 'Тип',
                'name' => 'Опис',
                'price' => 'Ціна',
                'nameDepartments' => 'Відділ',
                'nameExpenses' => 'Рахунок',
            );
        }
    
        public function getExpenses()
        {
            return $this->hasOne(Expenses::className(), ['id' => 'idexpense']);
        }
    
        public function getDepartments()
        {
            return $this->hasOne(Departments::className(), ['id' => 'iddepartment'])
                ->viaTable(Expenses::tableName(), ['id' => 'idexpense']);
        }
    
        public static function addPayments($input, $id)
        {
            $data = new Payments();
            $data->idexpense = $id;
            $data->name = $input['name'];
            $data->date = time();
            $data->type = $input['type'];
            $data->price = $input['price'];
            $data->save();
        }
    }


    Вюшка
    <?= GridView::widget([
                            'dataProvider' => $dataProvider,
                            'filterModel' => $searchModel,
                            'columns' => [
                                [
                                    'attribute'=>'date',
                                    'format' => 'date',
                                    'content'=>function($data){
                                        return date('Y-m-j G:i', $data['date']);
                                    },
                                ],
                                [
                                    'attribute'=>'nameDepartments',
                                    'format' => 'text',
                                    'content'=>function($data){
                                        return $data['departments']['name'];
                                    }
                                ],
                                [
                                    'attribute'=>'nameExpenses',
                                    'format' => 'text',
                                    'content'=>function($data){
                                        return $data['expenses']['name'];
                                    }
                                ],
                                [
                                    'attribute'=>'type',
                                    'format' => 'text',
                                    'content'=>function($data){
                                        return $data['type'] == 0 ? "Надходження" : "Видатки";
                                    }
                                ],
                                'name',
                                'price',
                            ],
                            'layout' => '{items}<div class="text-center">{pager}</div>',
                        ]); ?>
    Ответ написан
    Комментировать