Страницы

Поиск по вопросам

Показаны сообщения с ярлыком yii. Показать все сообщения
Показаны сообщения с ярлыком yii. Показать все сообщения

понедельник, 13 апреля 2020 г.

Добавление комментариев через ajax

#ajax #yii

                    
Привет! Требуется реализовать добавление комментариев через ajax, и как бы с этим
все понятно, но также требуется чтобы при добавлении комментария он был виден всем
участникам дискуссии находящимся на странице поста. Есть соображения как это реализовать
?    


Ответы

Ответ 1



Так же как делают чаты ajax - через ajax сообщение, написанное вами, отправляется в базу, и через ajax получаются сообщения в главном окне. Видели как в ВК изменятся время отправки запроса (1 минуту назад, 5 минут назад и т.д.). То же самое надо сделать и вам. Просто проверяйте, допустим, каждую секунду, базу данных на новые сообщения с помощью ajax

Ответ 2



Тут вроде норм описано, правда не для yii: Простая AJAX система комментариев

Ответ 3



Node.js и socket.io вам помогут. Кстати, эти технологии использованы в ВК. Правда разворачивать отдельное node.jd приложение нравится не всем, так что можно поискать что-то похожее. Создаем чат на Node.js и Socket.IO

Ответ 4



Вам нужно посмотреть в сторону реализации технологии comet на базе php и js.

суббота, 11 апреля 2020 г.

Документация для open-source проекта

#документация #php #yii #веб_программирование #opensource

                    
Привет всем!

Написал небольшую библиотеку на PHP. Теперь встал вопрос о создании сайта  для нее.
Сайт я решил делать с использованием Yii Framework. Ну и само собой разумеется, что
на сайте должна быть документация по работе с этой библиотекой: использование, написание
плагинов и прочее.

Вот хотел узнать, есть ли какие-нибудь готовые удобные системы по ведению документации.
Основные требования - это:


хранение всей документации в базе данных, а не в статичных HTML-файлах;
наличие веток или версионности. Например, есть документация для версии библиотеки
1.0. Но в версии 1.1 добавились некоторые возможности, которых нет в 1.0. Мне бы хотелось
не делать копию всей документации, а выбирать статьи, которые относятся только к определенным
версиям;
мультиязычность. Причем желательно, чтобы каждая отдельная статья, а не вся документация,
имела разные переводы. Чтобы в случае отсутствия перевода, показывать оригинал статьи;
подсветка или простое выделение кода.


Заранее спасибо.

P.S. В общем-то, все мои требования отражены на самом сайте Yii: Только, как я понимаю,
отдельных модулей и их исходников для создания такой документации самому нигде нет.

UPD:

Я думал, что таких систем видимо-невидимо в инете должно быть. А начал искать - не
нашел. Может, у них какое-то название есть специальное и я не так ищу?
    


Ответы

Ответ 1



Better late than never http://readthedocs.org/ + Версионность + Многоязычность + Автобилд - Все располагается на чужих серверах, можно забрать себе проект с github, но там вряд ли будет подробнейшая документация по поддержке своего сервера + Можно тарнслировать на своем сайте с помощью простого DNS + Подсветка кода + Поиск

Ответ 2



https://ru.wikipedia.org/wiki/PhpDocumentor - это отличный инструмент. Он позволит Вам и документацию вести, и подсказки для IDE будут генерироваться, и поддержка версий есть.

среда, 18 марта 2020 г.

Создание хорошего описания к коду

#yii #структуры #проектирование #проекты


Как возник данный вопрос, я, наверное, уже перейду к сути. Есть запрос на сервак,
у него 26 параметров. (мило правда?) запросов к серваку примерно может быть около 350!
в каждом от 5 до кучи передаваемых параметров.
Смысл в следующем, вот и вопрос.
У меня каждый запрос разбит на свой Action каждый action лежит в отдельном файле
//upd_start
Почему выбрано именно разбиение actions на файлы. Проект достаточно большой. Чтобы
все разработчики не расширяли сам контроллер, а просто дописывали в него 1-2 строчки
для подключения нового экшена + удобно редактировать проект такими кусками, а не целым
файлом, который бы терпел изменения постоянно. По мне так это правильно.
//upd_end
пример:
public function actions()
     {
     /* All actions in this controller 
      * are located in folder 
      * application.controllers.frontend.requests
      */
     return array(
                  'gf' => 'application.controllers.frontend.requests.gf',
                   // и т.д.
                );
      }

Первый вопрос:

На каком языке писать описание ко всему проекту?

В данный момент пытаюсь описывать на ENG, как может быть заметно из вышеописанной
функции, описание на ENG.
В gf.php описание тоже на ENG
@NumSeats          - The total number of passengers for which availability is being
requested
 @StartDt           - Date of Departure or Arrival. 
 @StartPt           - Airport or city code of the customer embarkation.
 @EndPt             - Airport or city code of the customer Destination.
 @StartTm           - Requested departure in 24-hour clock

В принципе, считаю что это правильно! В плане разработки проекта другими участниками,
как русско, так и англо говорящими.
Но есть одно но. Есть люди в компании не особо понимающие ENG язык и тем самым просят
комментировать код на русском языке.
В чем прикол? Ну на русском читать ведь проще! Соглашусь, переводить технический
ENG это пипец как "весело", схожу потихонечку с ума + ко всему не всегда получается
правильно перевести ENG на RUS в связи с разными обстоятельствами (незнание каких-то
оборотов и т.д.) В общем хватает веселых вещей по языкам.
Есть варианты решения, забить на ENG писать только на RUS второе решение писать только
на ENG, третье писать в 2х вариантах и в ENG/RUS что решит траблы обоих случаев, но
увеличит кол-во описания к коду, что на мой взгляд не есть хорошо.
Вот на стадии проектирования проекта и хочу выяснить как лучше делать.
С одной стороны хочется доставить всем удовольствие от разработки и писать описание
для всех, все равно приходится переводить мануал системы на RUS, с другой стороны писать
описалово на 2х языках муторно и как-то по кол-ву кода в файле слишком много.
Будет ли большое описание влиять на производительность кода?
последнее редактирование - 11.06.2013 15:32
Будут дополнения озвучу, пока все.
Жду ваших интересных отзывов по теме. 
Естественно буду продолжать открывать новые вопросы по теме разработки.    


Ответы

Ответ 1



@Shrek, не очень понял, что это за люди, которые хотят на русском. Если они будут сопровождать проект, то лучше делать комментарии на RUS. Если же это кто-то просто из любопытных заказчиков, то как Вам удобней (видимо, оставьте ENG). А писать комментарии в 2-х вариантах, это ни к чему. Тогда уж лучше их вообще не писать, т.к. через полгода один из вариантов точно уже не будет соответствовать коду.

суббота, 7 марта 2020 г.

Где хранить нетипичные файлы

#yii2 #yii


Вот, допустим, есть у меня php-файлик c самонаписанными функциями, и я хочу его везде
подключать.
В какой каталог его класть по правилам этого фреймворка?
    


Ответы

Ответ 1



Хранить кастомный файл можно где угодно. Нужно всего лишь работать с пространствами имен и подключать где нужно. Для примера создадим файл Person.php в папке helpers в корневой директории проекта. namespace app\helpers; //Указываем пространство имен для подключения в будущем class Person { public static function showName($name) { return "Привет $name"; } } Для того чтобы подключить выше созданный класс нужно сделать следующее: use app\helpers\Person; //используем пространства имен echo Person::showName("Urmuz"); //Используем статичный метод класса Person

Ответ 2



Смотря что там за функции. Можно оформить как behavior или как trait или это helper. Можно вынести на github и подключать через компосер, соответственно попадет в vendor или же закинуть в common в зависимости common/behavior common/trait common/helpers

четверг, 13 февраля 2020 г.

Зачем нужны темы в yii?

#php #yii


Здравствуйте. Подскажите, зачем нужны темы и когда лучше их использовать? Почему
бы не пользоваться просто представлением для разделения статических частей страницы
(шапка, футер)? Не совсем понимаю...
И еще, можно ли задавать несколько тем? Допустим для самого сайта, а потом для админской
панели? Как реализуется смена темы?    


Ответы

Ответ 1



Подскажите, зачем нужны темы и когда лучше их использовать? Для того же, для чего и в вордпрессе: для предоставления возможности разного дизайна одного и того же приложения без необходимости переписывать файлы. Также темы костыльно реализуют наследственность шаблонов: при задании шаблонов в дефолтной папке приложения их можно переопределить шаблонами в папке темы, и, таким образом, отобразить измененное представление в дефолтном лейауте и наоборот. Почему бы не пользоваться просто представлением для разделения статических частей страницы (шапка, футер)? Потому что в Yii сделан выбор в пользу общего шаблона (лейаута) и виджетов. Произвольные места в шаблоне все равно упираются в необходимость виджетов, и статические части просто становятся лишним грузом - их проще оформить в виде виджетов и не тратить время на поддержку ненужной сущности. Не говоря уж о том, что в серьезном приложении всегда находятся какие-нибудь промо-страницы, где все перевернуто с ног на голову, и тут проще уже написать отдельный лейаут. Ну и никто не мешает отдельные файлы в лейауте подключать. И еще, можно ли задавать несколько тем? Одновременно - нет, задавать произвольную тему при запросе - пожалуйста: Yii::app()->theme = 'default'; // используется тема default. Но, в общем, в этом нет большого смысла, этот функционал требуется крайне редко. Допустим для самого сайта, а потом для админской панели? Можно, но я бы не стал так делать. Вам надо задавать тему либо в конфиге, либо в рантайме, и это может быть просто лишней информацией. С другой стороны, если у вас разные конфиги для админки и фронтэнда, то почему бы и не развязать визуальные представления.

Ответ 2



Можно задавать сколько угодно тем. При использовании темы ее надо указать в конфиге: return array( 'name' => 'SiteName', 'theme' => 'themeDirectory' //Чувствительна к регистру в Unix-based системах //... ); Использовать можно на свое усмотрение, и сколько угодно (Например разрешить авторизированным пользователям выбирать тему самим, а неавторизированным писать ее же в куки) Вот небольшой Guide по темам

Yii2 или Laravel?

#laravel #php #yii


Что лучше для большого проекта - yii или laravel?
Знаю kohana.
Выбор фреймворка для нового проекта возложено на меня.
После моего старта проект будут дорабатывать другие программисты.
Не хочу ошибиться с выбором.
С каким фреймворком проще будет работать в команде?
Кода будет очень-очень много.
Проект огроменный.
Кэширование, оптимизация на первом плане.
Начал учить yii1. и как-то не нравится, не идет.
Все понимаю, и структуру тоже, но как-то все сложно сделано, или я не прав?
В общем, нужен совет на примере личного опыта.
Времени у меня неделя.    


Ответы

Ответ 1



Yii2 уже стабильный http://habrahabr.ru/post/240149/.

Ответ 2



Мой выбор пал на Laravel. Очень удобный фреймворк. Я получаю удовольствие, работая с ним.

Ответ 3



Неужели Kohana настолько плоха, что просто необходимо писать велосипеды на новом фреймворке? Большие важные проекты пишут на том, что хорошо знают. Если ничего не знаешь - бери модный Laravel, пару лет он будет в тренде.

Ответ 4



A Symfony2 вы не рассматриваете? Думаю, что лучше всего спросить у программистов, которые будут дорабатывать проект, какой фреймворк им больше подходит.

Ответ 5



Тут не всё так просто, я сам пишу на kohana (у которой есть свои сюрпризы), потому что он легкий и простой. Но вместо того чтобы ковырять Laravel или Yii2, возьмите Symfony2, так как это единственный верный вариант для большого проекта, я думаю со мной согласятся многие.

Ответ 6



У меня было невероятно короткое знакомство с Laravel, но он успел надоесть буквально своими объявлениями роутов, отсутствием неймспейсов и бесконечными анонимными функциями и статическими вызовами там, где они не нужны, так что из этих двух я не стал бы и выбирать. "Огроменность", вместе с тем, чуть ли не автоматом банит Yii 1.x и предполагает Symfony или Zend (последний не трогал, но его тоже рекомендуют для больших решений). но как то все сложно сделано, или я не прав? В Yii 1 вообще ни разу не сложно сделано.

Ответ 7



Yii2 - Это только для маленьких и средне-маленьких проектов. Он монолитный. И очень плохо расширяемый. Symfony2 - это только для средних и больших проектов. Хотя сейчас есть режим микроядра. Пока не пробовал. Laravel 5 - Это для маленьких, средних и средне-больших проектов. Хорошая расширяемость, отличная интуитивность и все совсеменное, что может предложить мир PHP и связанное с ним. Если вы не планируете приложение крайне огромных масштабов, я бы Выбрал Laravel 5. Он покроет большинство задач. Для остальных его можно расширить. :)

воскресенье, 26 января 2020 г.

Yii memcache http

#memcached #php #yii #nginx


Итак необходимо реализовать следующее:
Yii пишет в кеш данные, а далее данные должны быть доступны по адресу:
site.ru/_stat/ключ кеша 
В качестве сервера у нас нгинкс, ос: центОс. 
Итак:
if(!Yii::app()->cache->set($GameProposalModel->proposal_id, 'renderTable('.json_encode($toCache).')'))

Я записываю данные в кеш, к примеру ключ будет равен 30 ($GameProposalModel->proposal_id
= 30)
Далее идем на нгинкс:
   location /_stat {
        set            $memcached_key "$uri?$args";
        memcached_pass 127.0.0.1:11211;
        error_page     404 502 504 = @fallback;
        add_header Content-Type "text/html; charset=utf-8"; 
    }

    location @fallback {

        proxy_pass  http://localhost:9000;
    }

Далее я так прикинул, что по ссылку site.ru/_stat/30 я должен получить данные моего
кеша. 
Но я получаю только 502 Bad Gateway
Пример из
http://nginx.org/ru/docs/http/ngx_http_memcached_module.html
Подскажите пожалуйста в чем проблема ?    


Ответы

Ответ 1



Вы делаете запрос к сайту site.ru/_stat/30 . Запрос обрабатывает ядро YII - отвечает за это UrlManager согласно настройкам. Также необходимо глянуть что находиться в .htaccess. После работы UrlManager вызывается контроллер, выбирается его действие - передаются в действие все параметры - и действие выполняется. Поэтому вам нада в контроллере делать действие отвечающие за выборку кэша из memcached и отдачу его клиенту

четверг, 23 января 2020 г.

Проблема экспорта в CSV

#php #yii


Пытаюсь сделать экспорт отмеченных позиций CGridView в CSV.

Когда я передаю id отмеченных записей CGridView контроллеру методом $_POST, браузер,
вместо того чтобы показать запрос на открытие либо сохранение файла, возвращает ошибку
500 (причем FireBug показывает необходимые данные). 

Если же в запросе контроллера я вместо массива, передаваемого из представления пишу
обычный статичный массив - все прекрасно работает.

Подскажите пожалуйста, где я допустил ошибку?

Кнопка, отсылающая id записей контроллеру:

widget('bootstrap.widgets.TbButtonGroup', array(
    'type' => 'primary',
    'size'=>'mini',
    'buttons' => array(
        array(
            'label' => 'Export',
            'type' => 'success',
            'buttonType'=>'ajaxLink',
            'encodeLabel'=>true,
            'icon'=> 'th white',
            'url'=>Yii::app()->createUrl('/propertyPurchaseSale/ExportChecked'),
            'ajaxOptions'=>array(
            "type" => "post",
            "data" => "js:{ids:$.fn.yiiGridView.getSelection('property-purchase-sale-grid')}",
            "update" => '#', 'success'=>"js:function(data) {window.location.assign('/propertyPurchaseSale/ExportChecked');}"),
                                               
                                  array( //htmlOptions
                                        )                                    
                                    ),
                    array(
                        ...
                    ),
                    ),
                )); 
?>


Действие контроллера:

request->isAjaxRequest)
            {
                if(isset($_POST['ids']))
                {       
                    $idx = $_POST['ids'];
                    $count=Yii::app()->db->createCommand('SELECT COUNT(*) FROM property')->queryScalar();
                    // $sql='SELECT * FROM property WHERE id  IN (981, 982, 985)';
 --> when I use static values - all work
                    $sql="SELECT * FROM property WHERE id IN('".implode("', '",$idx)."')";
 // --> when I use join or implode function - data exist in firebug, but page return
error 500

                    $dataProvider=new CSqlDataProvider($sql, array(
                        'totalItemCount'=>$count,
                        'sort'=>array(
                            'attributes'=>array(
                                 'fullname', 'address', 'phone', 'db_number', 'created_date'
                            ),
                        ),
                        'pagination'=>false,
                    ));
                                        fputs($fp, $bom =( chr(0xEF) . chr(0xBB)
. chr(0xBF) ));
                                        if ($fp)
                                        {                        
                            echo    PropertyPurchaseSale::model()->getAttributeLabel("id").";".
                                        PropertyPurchaseSale::model()->getAttributeLabel("fullname").";".
                                    PropertyPurchaseSale::model()->getAttributeLabel("address").";".
                                    PropertyPurchaseSale::model()->getAttributeLabel("phone").";".
                                    PropertyPurchaseSale::model()->getAttributeLabel("db_number").";".
                                    PropertyPurchaseSale::model()->getAttributeLabel("created_date").
                                    " \r\n";                        
                            foreach ($dataProvider->getData() as $data) {
                                echo $data['id'] . '; ' . $data['fullname'] . ';
' . $data['address'] . '; ' . $data['phone'] . '; ' . $data['db_number'] . '; ' . $data['created_date']
. '; ' . "\r\n";
                            }
                }
                        exit;
                    }
                }
}    
?>

    


Ответы

Ответ 1



А что пишет в /runtime/application.log ? В Yii есть ActiveRecord, зачем SQL-запросами это всё делать? count(); ... $criteria = new CDbCriteria(); $criteria->addInCondition('id', $_POST['ids']); ... $dataProvider=new CActiveDataProvider('Properties', array( 'criteria' => $criteria, ... )); P.S. Класс Properties уже должен быть, если нет - сгенерируйте с помощью gii

Ответ 2



Сделайте то что вы уже сказали - конвертируйте $idx в массив, аналогично работающему статичному через $idx = array_map("intval", $_POST['ids']); И в implode можно сделать как implode(',', $idx); без пробелов и др. - там всё сделается автоматически; ну и поменять $sql="SELECT * FROM property WHERE id IN (".implode(',', $idx).")";

пятница, 10 января 2020 г.

Почему валидация выполняется, хотя должна выдавать ошибку?

#yii


Собственно ситуация такая:
Есть некоторая модель, в которой прописано следующее (делал по примеру):
public function rules()
{
    return array(
        array('begin_at', 'uniqueBeginAndEnd', 'message'=>'Сроки проведения с такими
условиями уже заданы'),
    );
}

public function uniqueBeginAndEnd($attribute,$params=array())
{
    if(!$this->hasErrors())
    {
        $params['criteria']=array(
            'condition'=>'courses_id=:courses_id AND end_at=:end_at',
            'params'=>array(':courses_id'=>(int)$_GET['id'], ':end_at'=>$this->end_at),
        );
        $validator=CValidator::createValidator('unique',$this,$attribute,$params);
        $validator->validate($this,array($attribute));
    }
}

Т.е. если я буду пытаться создать новую или редактировать уже существующую запись,
а запись с такими датами уже есть в таблице, то мне выдастся сообщение 'Сроки проведения
с такими условиями уже заданы'. 
Так вот в чем проблема: на добавление новой записи валидация работает, а на редактирование
нет (т.е. update проходит в любом случае).
Что добавление, что редактbрование делается стандартным $model->save()
P.S. Заранее извиняюсь, если объяснил не совсем внятно.    


Ответы

Ответ 1



я бы сделал что-то типа этого. public function rules() { return array( array( 'courses_id, end_at', 'unique', 'className' => 'название модели через которую ищем значение', 'attributes' => array('первовый атрибут', 'второй атрибут'), 'message' => 'Сроки проведения с такими условиями уже заданы'), array('courses_id, end_at', 'required'), array('courses_id, end_at', 'numerical'), ); } UPDATE И в таком случае стоит проверять что было передано от юзера, для этого нужны последние два правила. Я предположил что end_at это число. Если это дата то нужен валидатор date UPDATE 2 С учётом вашего комментария: На хеш-коде уже есть похожий вопрос с принятым ответом (легко ищется через яндекс по запросу "yii проверить уникальность") Коротко: вам нужно указать в правиле 'on'=>'add' //сработает при выполнении сценария добавления записи 'on'=>'edit' //при изменении записи

Ответ 2



Я делаю немного по другому валидацию, отличную от стандартных. Вот пример валидации имени товара: public function rules() { return array( array('name', 'filter', 'filter' => 'strip_tags'), array('name', 'filter', 'filter' => 'trim'), array('name', 'validItemName') ); } public function validItemName($attribute,$params=array()) { $pattern = "/[\!\?\"\'\+\_\/\|]/"; preg_match($pattern, $this->name, $matches); if($matches){ $this->addError('name', 'Недопустимый символ '.$matches[0]); } } Возможно и Вам следует добавлять самостоятельно ошибку через $this->addError()

Как правильно использовать функцию validateAuthKey() в yii2?

#php #yii #yii2


Я провёл исследования стандартного примера, и выяснил, что функция validateAuthKey()
вообще не вызывается. Для чего она тогда нужна, как её правильно вызвать, как правильно
с ней работать? 

public function validateAuthKey($authKey)
    {
        Yii::info('test ================');
        return $this->authKey === $authKey;
    }

    


Ответы

Ответ 1



validateAuthKey() проверяет $authKey - хэш, который хранится в куках. Вызывается для авторизации с помощью cookie в yii\web\User::loginByCookie при $enableAutoLogin = true protected function loginByCookie() { ... if ($identity->validateAuthKey($authKey)) { if ($this->beforeLogin($identity, true, $duration)) { $this->switchIdentity($identity, $this->autoRenewCookie ? $duration : 0); $ip = Yii::$app->getRequest()->getUserIP(); Yii::info("User '$id' logged in from $ip via cookie.", __METHOD__); $this->afterLogin($identity, true, $duration); } } ... }

Ответ 2



Если сессий нет (уничтожены) и при логинировании пользователя мы указывали «remenberMe» (то есть второй параметр метода Yii::$app->user->login(), чтобы кука установилась), то Yii2 попытаеся авторизовать пользователя с помощью куки, вот здесь-то и вызывается этот загадочный метод validateAuthKey() ... Естественно, попытка авторизации будет происходить только в том случае, если мы обращаемся к сущности пользователя, например так: if (!Yii::$app->user->isGuest) { echo Html::a('Выйти', ['logout']); } Это можно проверить, удалив сессии из временной папки сервера (то есть оттуда, где они храняться) и как-нибудь обозначить вызов validateAuthKey(), например так: public function validateAuthKey($authKey) { echo ''; return $this->getAuthKey() === $authKey; } Ну или помидитировать над исходными кодами Yii2. Источники: метод проб и ошибок документация; How to login user from a database in Yii Framework 2

суббота, 28 декабря 2019 г.

Yii framework или обычный php?

#framework #php #yii


Здравствуйте, гуру. Недавно узнал о неком волшебном Yii framework (да и вообще о
фреймворках на php). Посмотрел, да, вещь хорошая, но я не знаю стоит ли уходить с чистого
php на него, потому что 2 их я думаю трудноват о выучить (каша в голове будет)... В
Yii я делаю приложения немного быстрее, но на php привычней... Вот сижу мучаюсь, помогите
с выбором
PHP учу уже 1,5 года
    


Ответы

Ответ 1



Ну изначально тебе стоит изучать сам язык вне зависимости от того какой фреймворк на php ты будешь юзать. фреймворк и язык программирования разные вещи. Учи язык, фрейм поможет создавать приложения просто быстрее.

Ответ 2



На гуру не претендую, но могу сказать, что yii стоит того что его нужно изучить. Будет взрыв мозга.

Ответ 3



Все верно, используй Yii framework для развертывание проектов, если боишься забыть чистый php, возьми ученика кого нибудь_) обучение других, даст тебе отточенный инструмент, который в любое время будет готов к бою)

Ответ 4



Изучение фреймворков это хорошая практика) Хотябы для личного опыта. В них уже реализованны повседневные задачи, плюс вы застрахованны от ошибок при разработке(не от всех конечно). Вывод изучайте YII)

Ответ 5



Yii - фреймверк среднего уровня, надо начинать с более простого. http://habrahabr.ru/post/178833/

вторник, 17 декабря 2019 г.

Очередь задач в PHP

#очередь #php #yii


По мере создания своего проекта столкнулся с проблемой - есть некоторые действия
пользователей, которые могут длиться до нескольких минут. Ясно понятно, что заставлять
пользователя ждать, пока выполняются такие длинные запросы к серверу непозволительно!
И тут пришел к выводу, что нужно организовать очередь задач, чтобы пользователь нажал
ссылку, на сервере сформировалась задача, а пользователю лишь только отображался процесс
выполнения задачи.

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

Слышал о RabbitMQ, Apache Message Queue, но мне кажется, что они слишком избыточны
для моего случая. Мне нужно-то, делать некоторые проверки на сервере (тут как раз пригодился
бы способ выполнения PHP кода, и в зависимости от результата продолжалось бы выполнение
задач, или нет), и манипулировать учетными файлами, и просто "тяжелыми" файлами.

Где можно было почитать как организовывать подобные вещи? Может кто сталкивался уже
с этим, и нашел решение?

Проект создается на базе фреймворка Yii.
    


Ответы

Ответ 1



Воркер на пхп и запускать его по крону. Не?

Ответ 2



ПО мере создания своего проекта столкнулся с проблемой такого плана - есть некоторые действия пользователей, которые могут длиться до нескольких минут. Это ужасно! Это следствие плохой структуры БД и скриптов. Что такого может выполняться, да к тому же у каждого пользователя по минуте по две? Ладно обработка нескольких таблиц с математическими действиями по подсчете скидок у 16К клиентов и 25К заказов. Тут да у меня на серваке до 8 минут считаются, но раз в день и для всех сразу, а не для каждого по отдельности. Я даже набросал табличку в БД, и все бы хорошо, но решение получилось не универсальным. Созданная очередь задач умеет выполнять только шелл скрипты, а мне бы хотелось научить ее выполнять еще логику на php, и чтобы результаты обоих случаев складывались в БД. В Yii есть консольные приложения(и тут), юзай их. Делай там и логику и операции с данными. Не нужно изобретать с данном случае велосипед.

среда, 11 декабря 2019 г.

Горизонтальное масштабирование

#php #yii #mongodb #highload #масштабирование


Для одного из PHP + MongoDB проектов возникла необходимость осуществления горизонтального
масштабирования.


Учитывая, что будет использоваться несколько серверов, как лучше реализовать актуальность
своих же скриптов? Разные мелочи появляются довольно часто, как бы их из одного централизованного
хранилища сразу везде обновлять? sshfs, или gluster, или есть более простые способы?
В идеале хотелось бы иметь где-то директорию с ядром проекта, которое бы использовалось
напрямую остальными серверами.
Кэширование сейчас организовано в файловой системе, но, как я понимаю, будет необходимо
делать его общим для всех серверов. Как это делать лучше? Завести ещё одну БД под кэш,
или как-то ещё "выкручиваться"? Особенность у нас - в кэше есть данные общим объёмом
в несколько гигабайт, которые изменяются от силы раз в год, а используются чуть ли
не каждую минуту, именно из-за этого когда-то кэш не стали делать в redis. Как с такими
данными быть, тоже в БД? И какую БД для этого выбрать?
Правильно ли я понимаю, что при горизонтальном масштабировании сессии тоже 
необходимо хранить в БД?

    


Ответы

Ответ 1



Использовать сетевое хранилище для исходников - не самая лучшая идея. Каждый раз когда появляются разные мелочи - они должны пройти тестирование в отдельном окружении и только после этого следует использовать скрипт развертывания (deployment) актуальной версии и только на одном сервере, - после чего при помощи a/b-тестирования убедиться, что все работает как нужно. И только после того как все изменения протестированы, - запускать скрипт развертывания на остальных серверах. Использование файлового хранилища для исходников возможно, но это выглядит как неоправданная жертва стабильности в угоду удобству. Чем не подошел кэш в redis? - Несколько ГБ данных не создаст для него проблемы. Или вы имеете в виду, что одна запись в кэшэ занимает несколько ГБ ? - В таком случае следует разделить легкий и тяжелый кэш на раздельные сервисы. Нет. При горизонтальном масштабировании вы можете привязать пользователя к определенному серверу с которым он будет работать, в частности это используется для a/b-тестирования. В любом случае хранить сессии в реляционной БД не нужно, - они очень хорошо лежат в memcached.

воскресенье, 8 декабря 2019 г.

Как использовать Sphinx в Yii2 + PostgreSQL?

#php #yii2 #postgresql #yii #sphinx


Не до конца понимаю, возможно ли использование Sphinxsearch в Yii2 в качестве поискового
движка в связке с PostgreSQL? В экстеншене: Yii2-sphinx говорится про MySQL, но про
PgSQL ни слова. Сам экстеншен устанавливается, и конфиг вида:

'components' => [
    'sphinx' => [
        'class' => 'yii\sphinx\Connection',
        'dsn' => 'pgsql:host=localhost;port=5432;dbname=testdb',
        'username' => 'yii',
        'password' => '********',
    ],
]


ошибок не вызывает, даже при отсутствии Sphinx на сервере.
В связи с вышеизложенным возникает ряд вопросов:


Подходит ли данный экстеншен для использования его с PgSQL. Если да, где про это
можно почитать, или посмотреть реальные примеры (Yii2 + PgSQL + Sphinx)?
Стоит ли использовать его, или лучше что-то другое, вроде: pg-sphinx?
Стоит ли вообще его использовать, быть может есть решения быстрее и проще?


Стэк: Debian, Nginx, FPM, PHP7, Yii2, PgSQL

UPD Вопрос всё ещё актуален! :)
    


Ответы

Ответ 1



Первая фраза по ссылке yii2-sphinx в блоке Configuration, говорит о том, что используется только протокол MySQL: This extension interacts with Sphinx search daemon using MySQL protocol and SphinxQL query language. По идее, Вы можете попробовать добавить 'pgsql' => 'yii\sphinx\Schema' в массив $schemaMap, в файле Connection.php (в основной директории модуля), и, скорее всего простые запросы даже будут отрабатывать, но, как только будет более-менее сложный запрос, гарантирую, что Вы получите ошибку. Лучшим вариантом будет использование расширения pg-sphinx или похожее, если Вам действительно нужен Sphinx. В противном случае, попробуйте обычный полнотекстовый поиск, возможно, для ваших целей хватит и его.

вторник, 16 июля 2019 г.

Почему PDO::lastInsertId возвращает неверный ID при частых вставках в БД?

Существует веб-приложение (Win7x64, MS Sql Server 2012, Apache 2.4, PHP 5.6, Yii 1.1). Около сотни пользователей постоянно наполняют одну таблицу. В случае, если разные пользователи в одно и тоже время произвели вставку строки, первому возвращается ID вставленной строки второго и дальнейшие действия, например сохранение истории изменений, ведется с неверным ID. Yii использует PDO, в частности метод lastInsertId для получения айдишника, но описания подобной проблемы в интернете не встретил.
Для чистоты эксперимента, я создал две новые таблица Collision и CollisionHistory:
CREATE TABLE [dbo].[Collision]( [id] [int] IDENTITY(1,1) NOT NULL, [uuid] [varchar](50) NULL, CONSTRAINT [PK_Collision] PRIMARY KEY CLUSTERED ( [id] ASC ) ON [PRIMARY] )
CREATE TABLE [dbo].[CollisionHistory]( [id] [int] IDENTITY(1,1) NOT NULL, [collision_id] [int] NULL, [uuid] [varchar](50) NULL, CONSTRAINT [PK_CollisionHistory] PRIMARY KEY CLUSTERED ( [id] ASC ) )
На их основе в gii генерю модели. В модель Collision добавляю код:
public function afterSave(){ parent::afterSave(); $history = new CollisionHistory(); $history->collision_id = $this->id; $history->uuid = $this->uuid; $history->save(false); }
Пишу контроллер
class CollisionController extends CController {
public function actionTest() { for ($i = 0; $i < 1000; $i++) { $model = new Collision(); $model->uuid = $this->UUIDv4(); $model->save(false); } }
private function UUIDv4() { return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff) ); }
}
Затем на счет три с коллегой запускаем actionTest каждый со своего компьютера. В итоге на 2000 инсертов в таблицу Collision 419 повторений collision_id в таблице CollisionHistory.
Почему такое происходит и как этого избежать?


Ответ

Провел тест на чистом PDO, поменял несколько версий, но результат тот же. Метод PDO::lastinsertid возвращает самый последний id для таблицы, как функция MSSQL IDENT_CURRENT()
То есть, если между вставкой и получением id произошла вставка в другой сессии, то возвращается id из второй сессии.
Свою проблему решил созданием хранимой процедуры для вставок в самую часто-используемую таблицу, в которой выходной параметр заполняется функцией SCOPE_IDENTITY().
Кстати, используя выходной параметр в хранимой процедуре, не стоит забывать про инструкцию SET NOCOUNT ON, которая отключает вывод количества затронутых процедурой строк вместо выходного параметра.

понедельник, 25 февраля 2019 г.

Как правильно использовать функцию validateAuthKey() в yii2?

Я провёл исследования стандартного примера, и выяснил, что функция validateAuthKey() вообще не вызывается. Для чего она тогда нужна, как её правильно вызвать, как правильно с ней работать?
public function validateAuthKey($authKey) { Yii::info('test ================'); return $this->authKey === $authKey; }


Ответ

validateAuthKey() проверяет $authKey - хэш, который хранится в куках. Вызывается для авторизации с помощью cookie в yii\web\User::loginByCookie при $enableAutoLogin = true
protected function loginByCookie() { ... if ($identity->validateAuthKey($authKey)) { if ($this->beforeLogin($identity, true, $duration)) { $this->switchIdentity($identity, $this->autoRenewCookie ? $duration : 0); $ip = Yii::$app->getRequest()->getUserIP(); Yii::info("User '$id' logged in from $ip via cookie.", __METHOD__); $this->afterLogin($identity, true, $duration); } } ... }

пятница, 12 октября 2018 г.

Как использовать Sphinx в Yii2 + PostgreSQL?

Не до конца понимаю, возможно ли использование Sphinxsearch в Yii2 в качестве поискового движка в связке с PostgreSQL? В экстеншене: Yii2-sphinx говорится про MySQL, но про PgSQL ни слова. Сам экстеншен устанавливается, и конфиг вида:
'components' => [ 'sphinx' => [ 'class' => 'yii\sphinx\Connection', 'dsn' => 'pgsql:host=localhost;port=5432;dbname=testdb', 'username' => 'yii', 'password' => '********', ], ]
ошибок не вызывает, даже при отсутствии Sphinx на сервере. В связи с вышеизложенным возникает ряд вопросов:
Подходит ли данный экстеншен для использования его с PgSQL. Если да, где про это можно почитать, или посмотреть реальные примеры (Yii2 + PgSQL + Sphinx)? Стоит ли использовать его, или лучше что-то другое, вроде: pg-sphinx? Стоит ли вообще его использовать, быть может есть решения быстрее и проще?
Стэк: Debian, Nginx, FPM, PHP7, Yii2, PgSQL
UPD Вопрос всё ещё актуален! :)


Ответ

Первая фраза по ссылке yii2-sphinx в блоке Configuration, говорит о том, что используется только протокол MySQL:
This extension interacts with Sphinx search daemon using MySQL protocol and SphinxQL query language.
По идее, Вы можете попробовать добавить 'pgsql' => 'yii\sphinx\Schema' в массив $schemaMap, в файле Connection.php (в основной директории модуля), и, скорее всего простые запросы даже будут отрабатывать, но, как только будет более-менее сложный запрос, гарантирую, что Вы получите ошибку.
Лучшим вариантом будет использование расширения pg-sphinx или похожее, если Вам действительно нужен Sphinx. В противном случае, попробуйте обычный полнотекстовый поиск, возможно, для ваших целей хватит и его.