Задать вопрос
  • Как ускорить создание большого прайса?

    @marsdenden
    Есть еще интересный хак - сформировать html с < table >< / table >, сохранить его как xls - любой excel открывает такой файл, не чихая. Правда, на таких объемах я это не тестировал.
    Ответ написан
  • Linux дистрибутив для предприятия?

    @marsdenden
    Поддержите "отечественного производителя" - посмотрите на АльтЛинукс, фирма Базальт (недавно перебрендились), basealt.ru
    Использую на сервере, правда, без ui, уже лет 10, правда админю сам, но у них и поддержка есть.
    Ответ написан
  • Javascript-фреймворки/движки для создания сайта, работающего в браузере клиента?

    @marsdenden
    Я пользуюсь vue.js
    Ответ написан
    Комментировать
  • В чем суть SPA?

    @marsdenden
    Суть в том, что вместо перехода по ссылкам и загрузки новой страницы при каждом клике по ссылке происходит подгрузка некоторых данных через тот же axios во vue. И тот же vue отвечает за отображение этих данных. То есть SPA - это самое что ни на есть разделение на бэкенд и фронтенд - серверную и клиентскую часть. Ничего сложного.
    SPA - single page application, то есть одностраничное приложение. Загрузка страницы происходит один раз, а дальше - запрос-ответ. Благодаря этой схеме при первоначальной загрузке грузятся все стили и скрипты (которые уже содержат шаблоны в себе) и дальнейший обмен с сервером получается достаточно экономичным с точки зрения трафика, что положительно влияет на загрузку сервера и скорость получения данных.
    Ответ написан
    7 комментариев
  • Вопрос по поводу ajax добавления новых записей на страницу при скроллинге и клике?

    @marsdenden
    Такой подход сильно усложняет код, посмотрите в сторону фреймворков - Vue.js, React. Ну или шаблонизатор lodash на худой конец.
    Ответ написан
    Комментировать
  • Клиент RDP - черный экран после сворачивания-разворачивания сессии - как исправить?

    @marsdenden Автор вопроса
    Ура! Решено! Смена глубины цвета на 24 бита - и все нормально
    Ответ написан
    1 комментарий
  • Как внедрять vue.js в существующий проект?

    @marsdenden
    В конце концов все равно придётся переделывать все полностью. Я пришёл именно к этому, поскольку слишком разные подходы - сборка проекта SPA и попытка постепенного внедрения.
    Ответ написан
    Комментировать
  • VueJS + PHP. Как это всё подружить?

    @marsdenden
    vue-router сам по себе, роутер на php - сам по себе, никак между собой не связаны. Если от бэкенда нужны только данные и никакого дополнительного функционала, я бы попробовал сделать сервер на ноде, благо модули готовые есть, по крайней мере писать на одном языке проще и эффективнее, чем на двух (имхо). А так все просто - фронт использует axios, в который передается url, параметры и callback для обработки ответа. Бэк обрабатывает вызов и отправляет JSON с данными и на этом его миссия закончилась, фронт в колбэке получает json и делает свое дело.
    Например, как я это сделал (метод - всегда POST)

    в App.vue в methods
    callApi(url,prms,callback){
      this.setServerError('',''); // это функция, которая в data выставляет определенные поля
      //в результате чего ошибки выводятся прямо на странице, удобно для отладки
      axios({
        method:"post",
        url:url,
        data:prms
      }).then((response) => {
        // в response.data получаем JSON, 
        // в моем случае сервер формирует обязательные поля success,error,buffer
        // в buffer  перед выдачей JSON снимается html-вывод, возможно это отладочная информация,
        // которую выдает backend, возможно PHP-warnings
        let dt=response.data;
        if(!dt.success){
           	this.setServerError(dt.error,dt.buffer);
        }else{
            // ну и, собственно, сам вызов колбека, который происходит только в случае успешного приема данных
            callback(dt);
        }
      }).catch((error) => {
        // эту часть вызывает сам axios при возникновении серверных ошибок, то есть все, что не 200 OK 
        // позволяет увидеть, в частности, ошибку 500, вернее сам факт ее возникновения, если она обрабатывается
        // "стандартным" методом апача - пустая страница и все
        this.setServerError(error.message,error.stack);
      });
    },



    далее в created создается подписка, можно использовать Bus.js, у меня по другому

    this.$root.$on('callApi',(url,prms,callback)=>{this.callApi(url,prms,callback)});


    ну и в компоненте или где еще в проекте делается вызов

    this.$root.$emit('callApi', '/api/goods', {action: 'getgoodsinfo', article: '12345678'}, (dt) => {
             this.articleinfo=dt.data.articleinfo;
          })


    на бэкэнде, соответственно, есть api.php, в котором происходит разбор url, чтение параметров и формирование результата

    заготовка api.php
    <?php
    // регистрируем функцию завершения, чтобы обрабатывать грубые ошибки, 
    //например вызов несуществующего метода у объекта
    register_shutdown_function(function () {
        $error = error_get_last();
        if ($error && ($error['type'] == E_ERROR || $error['type'] == E_PARSE || $error['type'] == E_COMPILE_ERROR)) {
            $res=array(
                'buffer'=>ob_get_contents(),
                'success'=>false,
                'error'=>"PHP Fatal: ".$error['message']." in ".preg_replace('/(.*)\/(.*)/', "$2", $error['file']).":".$error['line']
            );
            ob_clean();
            header('HTTP/1.1 200 Ok');
            header("Access-Control-Allow-Origin: *");
            echo json_encode($res);
            // ... завершаемая корректно ....
        }
    });
    
    // для кроссдоменного CORS, при необходимости - закомментировать или заменить звездочку на требуемое
    if($_SERVER['REQUEST_METHOD']=='OPTIONS' ){
        ob_clean();
        header("Access-Control-Allow-Origin: *");
        header("Content-type: application/json; charset=utf-8");
        header("Access-Control-Allow-Headers: X-Requested-With, Content-Type");
        header("Access-Control-Request-Method: POST");
        return true;
    }
    
    // /*
    // протокол обмена
    // - вход - команда по сегменту, например http://site.ru/api/goods - api - попали сюда, goods - команда REST
    // в php://input должен быть json, в котором обязателен параметр action, например getgoodsinfo
    // в результате формируется имя функции класса goods_getgoodsinfo, которая вызывается 
    // с параметром входящего json
    
    // функция класса должна вернуть массив с тремя полями - data & success & error
    // в поле data возвращается непосредственно результат функции, в нашем случае - реестр чеков
    // в поле success возвращается true | false - признак успешного выполнения
    // в поле error возвращается описание ошибки в случае неудачного выполнения функции
    // */
    
    $api=new ApiCls();
    
    // функция, проверяющая залогиненность юзера
    if(is_user_login()){ 
        $api->checkcommand();
    }else{
        $res=array('succes'=>false,'error'=>'Пользователь не авторизован','data'=>'');
        ob_clean();
        header("Content-type: application/json; charset=utf-8");
        header("Access-Control-Allow-Origin: *");
        header("Access-Control-Allow-Headers: X-Requested-With, Content-Type");
        echo json_encode($res);
    }
    
    return true;
    
    class ApiCls{
        function checkcommand(){ // точка входа для класса api, здесь первичный разбор, 
            //вызов метода и возврат результата
            // главное - определить второй сегмент в url, то есть в случае http://site.ru/api/goods
            $segment=????????; // в $segment должен оказаться 'goods'
    
            $res=array('success'=>false,'error'=>'Empty action'); // сразу проверка на наличие action в параметрах
            if(!$segment){
                $res['error']='Empty command';
            }else{
                if($_SERVER['REQUEST_METHOD']=='PUT' || $_SERVER['REQUEST_METHOD']=='POST'){
                    $reqdata = file_get_contents('php://input'); 
                    $b=json_decode($reqdata);
                    $b=get_object_vars($b);
                    if(isset($b['action'])){
                        $res['error']='no error';
                        $nm=$segment.'_'.$b['action'];
                        $r=$this->$nm($b); // вызов метода по action из пост и дальнейшая обработка результатов
                        // чё-то тут намутил, но работает - и ладно
                        if(!isset($r['success'])){
                            $res['success']=false;
                            $res['error']='No success flag in method '.$nm;
                        }else{
                            if(!isset($r['data'])){
                                $res['success']=false;
                                $res['error']='No result data in method '.$nm;
                            }else{
                                $res['success']=$r['success'];
                                $res['data']=$r['data'];
                                if(!$r['success']){
                                    if(isset($r['error'])){
                                        $res['error']=$r['error'];
                                    }else{
                                        $res['error']='Success is false, but no error message in method '.$nm;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            // непосредственная выдача данных
            $this->_printresponse($res);
        }
        function _printresponse($res){
            // проверяем наличие html-вывода (отладка или warnings)
            $res['buffer']=ob_get_contents();
            if($res['buffer']!=''){
                $res['success']=false;
                isset($res['error'])?$res['error']=implode(',',array('module error',$res['error'])):$res['error']='module error';
            }
            // очищаем буфер вывода и формируем свои заголовки
            ob_clean();
            header("Content-type: application/json; charset=utf-8");
            header("Access-Control-Allow-Origin: *");
            header("Access-Control-Allow-Headers: X-Requested-With, Content-Type");
            // ну и, наконец, выдаем результирующий JSON
            echo json_encode($res);
        }
        function __call($name,$post){
            // эта функция вызывается при попытке вызвать несуществующий метод класса, то есть при вызове '/api/blablabla' получим отлуп
            $info=array('method'=>$name,'post'=>$post,'error'=>'Method not found','success'=>false);
            return $info;
        }
        /*********************************************************/
        // начинаем блок методов api
        function goods_getgoodsinfo($prm){
            // формируем заготовку ответа
            $res=array('data'=>array(),'success'=>true,'error'=>'');
            // при необходимости здесь можно вставить проверку наличия полномочий у пользователя
            // и если что не так, то выключить success, прописать "облом!" в error и не возвращать данные
            $res['data']['articleinfo']= getArticleInfo($prm['article']); // вызов функции, 
            //которая собирает требуемые данные для определенного артикула и возвращает, опять же
            // в формате JSON
            return $res;
        }
    }
    ?>



    Вот как-то так... Дальше только вопрос - как прикрутить этот api.php к сайту и вопросы безопасности, но это уже другая тема
    Ответ написан
    1 комментарий
  • Тупой вопрос: Как остановить скрипт в отладчике браузера?

    @marsdenden
    тупой ответ - поискать кнопку паузы. Не допускать ухода в бесконечный цикл. Иначе ваш аппарат никогда не приземлится на Марсе
    Ответ написан
    3 комментария
  • Не выводится сообщение ajax при успешной отправке формы, в чем причина?

    @marsdenden
    если судить по этому, то надо что-то сделать с formData. Если совсем уж точно, то преобразовать в строку, а не отправлять объект как таковой. Видимо, jQuery все же не настолько умен, чтобы преобразовывать объекты. И еще не мешает поглядывать в консоль (F12 в Firefox/Chrome)

    data: JSON.stringify(formData),
    Ответ написан
    Комментировать
  • Ext JS 6.2.0 Classic, как управлять полосой прокрутки Ext.grid.Panel?

    @marsdenden Автор вопроса
    и опять форум сенча вне конкуренции! Помогли решить вопрос практически мгновенно ))
    а именно - в секции, описывающей центральную панель, в которую помещается грид надо прописать layout:"fit" и убрать явное задание высоты и ширины
    {
            region:"center",
            collapsible:false,
            items: [{
                xtype: 'clientslist'
            }],
            layout: "fit",
    }
    Ответ написан
    Комментировать
  • Как отследить изменение текста поля ввода?

    @marsdenden
    Я понимаю, что уже много времени прошло, но на будущее

    $(document).on("input",function(ev){
      console.log($(ev.target).val());
    });


    ловит все изменения, включая копипаст
    Ответ написан
    Комментировать
  • Кто писал свою CMS?

    @marsdenden
    Посмотри на MaxSiteCMS.
    Макс некоторый русофоб, однако систему наваял скоростную. Есть на гитхабе репозиторий, все в открытом виде, есть некоторое сообщество, для блогов идеальная система, но я ее уже года два пилю совсем не для блоговой тематики.
    Разобравшись с этой системой (не так сложно), можно форкать свою ветку, хотя смысла не вижу - разработка идет, поддержка есть, свое прикрутить - вообще не проблема, система работает на Codeigniter 2.x, активно юзаю jQuery, шаблонизатор lodash - получается некий свой фреймворк внутри CMS. Концепция плагинов отделяет ядро от всего навесного, шаблоны тоже можно менять. Я все свои навороты реализую именно как плагин+шаблон.
    Для верстки там свой UniCSS, компилятор SASS (раньше использовал LESS)
    Ответ написан
    Комментировать
  • Почему говорят что jquery не нужен?

    @marsdenden
    ну кто-то считает, что и российские машины не нужны, однако нашу Ниву теперь китайцы покупают, да еще и в два раза дороже, чем мы.
    Все зависит от потребностей.
    И один нюанс - лучше грузить не со сторонних ресурсов, а со своего сервера - буквально вчера наткнулся на сайт, который выдал что-то вроде "$ not reference" - то есть тупо не смог подгрузить и все! конечному юзеру облом ))
    Ответ написан
  • Как на delphi вызвать метод com объекта, название которого на момент написания программы неизвестно?

    @marsdenden Автор вопроса
    В общем, вопрос решен. Используя методы IDispatch (которым и является результат CreateOleObject) можно узнать, какие методы и свойства имеются в подключаемом COM-объекте и уже дальше использовать Invoke
    Ответ написан
    Комментировать
  • Компилятор выполняет код в комментарии, как такое может быть!?

    @marsdenden
    не очень хорошее решение - прописывать абсолютные пути. Лучше использовать относительные, тогда целиком папки можно переносить и открывать и таких косяков не будет
    Ответ написан
    Комментировать
  • Как реализовать регистрацию и авторизацию ajax+python?

    @marsdenden
    ну как бы для вашего случая не "из html" отправляются данные, а посредством javascript. При использовании jQuery методы ajax, post, get. Это на стороне клиента. А уж питон на стороне сервера, должен обрабатывать url, по которому и передаются данные для авторизации.
    При ajax-запросах стандартная отправка "из html" не используется вовсе, она эмулируется методами jQuery ajax, post, get.
    Ответ написан
    Комментировать
  • Почему не стоит использовать BBCode?

    @marsdenden
    Примерно то же самое с CodeIgniter. Версия 2.Х вполне себе работоспособная и обкатанная, однако "надо идти вперед" и появляется версия 3. Сыровата и с глюками, "но это же последняя версия!".
    Старое - не значит плохое. Понты обычно вылазят боооольшим боком. Ну и бритва Оккама вам в помощь ))
    Ответ написан
    Комментировать
  • Как средствами PHP CURL выполнить CORS запрос на другой домен?

    @marsdenden Автор вопроса
    Можно считать вопрос закрытым. Проблема не в options.
    ответ на вопрос
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'OPTIONS');

    запрос OPTIONS проходит нормально, но, тем не менее, авторизация не идет. Буду искать дальше
    Ответ написан
    Комментировать