• Как победить ошибку "Cannot access before initialization"?

    @Delagen
    Техногик
    У вас классический пример циклической зависимости, вынесите NDS в отдельный модуль, а то у вас получается цепочка загрузки app -> methods -> app
    Ответ написан
    Комментировать
  • Что выбрать: ставить или не ставить слэш на конце URL?

    @pazitiffcheg
    Для тех, кто утверждает, что слеш в конце url нужно ставить и что веб-сервер очень напрягается, если слеш не поставить, прошу выложить кусок кода из apache или nginx отвечающий за реализацию данного алгоритма - это же opensource проекты, всё в свободном доступе.
    Поисковикам же совершенно всё равно, по какому адресу обрабатывать страничку, главное чтоб небыло задвоения, поэтому в правилах веб-сервера делаем 301 редирект на какой либо из вариантов.
    Поисковики не панацея интернета, и как заметил уважаемый IlVin IlVin
    "В www.ietf.org/rfc/rfc1738.txt этот вопрос не регламентирован."
    Поисковики пишут универсальные алгоритмы для того чтобы их поиск был качественен, но они не распоряжаются, как должен работать тот или иной веб сервер. Есть запрос по url и есть ответ - всё просто.
    Сам я терпеть не могу, когда попадается сайт со слешами на конце особенно г..сайтах. Сайту и так плохо, так еще какой то не компетентный СЕОшник еще больше его запорол.....

    Люди, не перебарщивайте и не втирайте про слеш на конце, он там вообще не нужен, т.к. в url нет понятия "Директория" - это не файловая система. URL - это адрес, состоящий из символов, слеш определяет структуру адреса, только и всего.
    Ответ написан
    Комментировать
  • Как реализовать автоматическое соединение Websocket при падении сервера?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    1. setInterval вообще не нужен
    2. this.socket = new WebSocket - на этой строке в строгом режиме будет ошибка (this === undefined), а в нестрогом (почему его нет?) создаст socket в глобальном объекте (что плохо)
    3. После создания соединения, события нужно снова навесить

    У меня лично вот так вот все организовано:
    const url = `${location.protocol === 'http:' ? 'ws:' : 'wss:'}//${location.host}/`;
    
    var socket;
    var connected = false;
    
    typeof WebSocket !== 'undefined' && function connect() {
        socket = new WebSocket(url);
        socket.onmessage = onMessage;
        socket.onopen = () => connected = true;
        socket.onerror = err => {
            console.error(err);
            socket.onclose = null;
            connected = false;
            socket.close();
            connect();
        };
        socket.onclose = event => {
            console.info(`WebSocket closed with code ${event.code}! ${event.reason}`);
            connected = false;
            if(event.wasClean) return;
            connect();
        };
    }();
    
    function onMessage(event) {
        //...
    }
    Ответ написан
    1 комментарий
  • Как объединить два объекта javascript с заменой значений по ключу, если он существует?

    @paulvoloschuk
    Object.assign
    Линк

    var a = {a:1, b:2, c:3};
    var b = {a:2, b:2};
    
    console.log(Object.assign(a,b));   // result Object {a: 2, b: 2, c: 3}
    Ответ написан
    Комментировать
  • Подскажете хороший datepicker для Vue2?

    LeeMasagos
    @LeeMasagos
    E-commerce
    Ответ написан
    Комментировать
  • Что конкретно делает эта функция mysqli_real_escape_string()?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Это хороший вопрос, в первую очередь потому что найти человека, который знает правильный ответ, практически нереально. Опроси 10 похапешников, 10 из них тебе наплетут ереси, которая не имеет с реальностью ничего общего. Любой, кто заикнется про SQL инъекции, уже облажался.

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

    Как ты, наверное, уже знаешь, строки в SQL берутся в кавычки:
    SELECT * FROM table WHERE name='vasya'
    Вот чтобы vasya не приняли за имя таблицы или ключевое слово, его берут в кавычки. Очень просто. Но иногда у человека имя не просто вася. Что будет вот с таким запросом?
    SELECT * FROM table WHERE name='Я Д'Артаньян, а все вокруг ...'

    Мясорубка будет. БД решит, что имя - это 'Я Д', а дальше какая-то фигня, которую она не понимает. И выдаст ошибку.
    Поэтому кавычки надо экранировать.
    SELECT * FROM table WHERE name='Я Д\'Артаньян, а все ...'

    никаких ошибок не выдаст.
    Вот mysqli_real_escape_string() как раз этим и занимается - экранирует кавычку слешем, а заодно и сам слеш, потому что если слеш окажется в конце строки,
    SELECT * FROM table WHERE text='Мну сегодня в любви вкладкой ошиблись :\'

    то БД решит, что последняя кавычка экранирована, и строка не заканчивается. Снова мясорубка.
    Также mysqli_real_escape_string() экранирует еще несколько символов, но уже из чисто эстетических соображений.

    Еще одна функция этой функции - принимать в расчет кодировку текста. Есть кодировки, в которых слеш - это не слеш, а часть другого символа. И когда БД будет парсить запрос, она не поймет, что это слеш, а решит что это просто буква. И снова мясорубка.
    Поэтому перед использованием mysqli_real_escape_string() надо сказать БД, в какой кодировке у нас данные, с помощью функции mysqli_set_charset().

    Но читатель уж сучит ножками в нетерпении - а что же SQL инъекции, о которых так долго говорили большевики? Не может же быть, чтобы они были совсем не при чем. Окей, в качестве побочного эффекта, строка, в которой экранированы спецсимволы (слеш и кавычка), не пропустит инъекцию. Но здесь следует понимать две вещи:

    1. Строки надо форматировать в любом случае, независимо от того, ждем мы инъекцию, или нет. Мясорубка нам точно так же не нужна.
    2. Строками синтаксис SQL запросов не исчерпывается. Есть числовые литералы, есть имена полей. Для всех них mysqli_real_escape_string() бесполезна чуть более чем полностью.

    То есть, отсюда можно сделать вывод, что нельзя использовать mysqli_real_escape_string() для защиты от инъекций. Она предназначена для другого. Вот для этого другого, для форматирования строк, ее использовать можно. Но не нужно.

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

    В принципе, mysqli умеет так делать, но не так удобно как PDO. Поэтому при возможности вместо нее лучше использовать PDO:
    $stmt = $pdo->prepare("SELECT * FROM table WHERE name=? or name=?")
    $stmt->execute(["Vasya", "Д'Артаньян"]);
    $rows = $stmt->fetchAll();
    - и получить, в итоге, готовый массив с данными, которые вернула БД.
    Если же возможности нет, то кода придется написать чуть побольше
    $stmt = $mysqli->prepare("SELECT * FROM table WHERE name=? or name=?")
    $stmt->bind_param("ss", ...["Vasya", "Д'Артаньян"]);
    $stmt->execute();
    $rows = $stmt->fetch_all(MYSQLI_ASSOC);


    Но при этом всё равно никакой тебе возни с кавычками, слешами, real, escape, и прочей ерундой. Просто, быстро, лаконично и безопасно.
    Ответ написан
    4 комментария
  • Как сделать универсальный метод для правки input на лету?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Меняет только value в input без изменения модели

    v-model слушает событие input, так что добавьте event.target.dispatchEvent(new Event('input'))
    Ответ написан
    3 комментария
  • Как в Symfony 5 проверить роль любого пользователя?

    BoShurik
    @BoShurik Куратор тега Symfony
    Symfony developer
    Security работает именно с залогиненым пользователем. Если вам надо проверить другого пользователя, то надо делать что-то вроде:
    /** @var UserInterface $user */
    /** @var RoleHierarchyInterface $hierarchy */
    
    $roles = $hierarchy->getReachableRoleNames($user->getRoles());
    $result = array_search('ROLE_GROUP_MANAGER', $roles) !== false;
    Ответ написан
    1 комментарий
  • Как задать глобальные методы в Vue?

    kulakoff
    @kulakoff Куратор тега Vue.js
    Vue.js developing
    Также можно использовать механизм примесей: https://ru.vuejs.org/v2/guide/mixins.html

    Создаете объект примеси:
    // определяем объект примеси
    var myMixin = {
      created: function () {
        this.hello()
      },
      methods: {
        hello: function () {
          console.log('привет из примеси!')
        }
      }
    }


    И далее его можно инжектить в любой компонент или глобально:
    Vue.mixin(myMixin)
    Ответ написан
    2 комментария
  • Как пользоваться Transliterator?

    Vasiliskov
    @Vasiliskov
    Упрощённый вариант, без раскуривания доки по транслитерейту:
    transliterator_transliterate('Latin-ASCII', transliterator_transliterate('Latin', $sourceString));
    Ответ написан
    Комментировать
  • Как пользоваться Transliterator?

    27cm
    @27cm
    TODO: Написать статус
    function slugify($string) {
        $translit = "Any-Latin; NFD; [:Nonspacing Mark:] Remove; NFC; [:Punctuation:] Remove; Lower();";
        $string = transliterator_transliterate($translit, $string);
        $string = preg_replace('/[-\s]+/', '-', $string);
        return trim($string, '-');
    }
    
    echo slugify("Я люблю PHP!");

    Источник: php.net/manual/ru/transliterator.transliterate.php...
    Ответ написан
    Комментировать
  • Как в динамической таблице по Enter передавать фокус следующему Input?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Если решение нужно универсальное, то правильным будет следовать той же логике что tab.
    Например использоват tabbable(или любую иную подобную либу) на корневой form, и отталкиваясь от позиции элемента фокусировать следующий.
    Потому что визуально элементы не обязательно следуют в том же порядке, что и в dom, и также не обязательно, что следующим в фокусе должен быть именно следующий по порядку. Для всего этого и придуман tabindex.
    Ответ написан
    Комментировать
  • Как в динамической таблице по Enter передавать фокус следующему Input?

    Kozack
    @Kozack Куратор тега Vue.js
    Thinking about a11y
    Я бы сделал как-то так
    this // текущий input
      .closest('tr')
      .nextElementSibling
      .querySelector('input.find-me-vue')
      .focus()

    Но, нужно ещё предусмотреть ряд исключений
    Ответ написан
    3 комментария
  • Когда нужно использовать computed, а когда methods во Vue.js? И в чем их разница?

    Decadal
    @Decadal
    Если результат вашей функции не опирается на внутренние данные, используйте methods.
    Например, у вас есть внутри vue некая range, которая служит верхней границей для Math.random. Если реализовать при помощи метода, то каждый раз он будет возвращать новое значение Math.random.
    Реализация через computed будет ожидать изменений вашего range, а иначе вернет то же число, которое сгенерилось первый раз
    js:
    var app = new Vue({
            el: '#content',
            data: {
                range: 1
            },
            computed: {
                rand: function () {
                    return Math.random() * this.range ; //ожидалось что app.rand будет давать случайное число
                }
            },
            methods: {
                show: function (event) {
                    alert('Случайное число: ' + this.rand); // но нет, число одно и то же
                },
           }
    });

    html:
    <div id="content">
    <button v-on:click="show">показать число</button>
    </div>


    В итоге оно сгенерирует число один раз и будет выводить его постоянно при клике на кнопку. Если вы введете в консоли app.range = 2; то генерируемое число разово изменится.

    Пример для лайков, упомянутый в комментарии:
    new Vue({
       el: '#content',
       data: {
          likes: 0,
       },
    });

    <div id="content"><button v-on:click="likes += 1">+1</button></div>
    Ответ написан
    9 комментариев
  • Как распарсить XML файл в массив?

    @Panda_Tamara
    Разработчик проектов под UMI.CMS
    Ловите велосипед. Для вызова передаете объект XMLReader и ноду для начала парсинга. Возвращается ассоциативный массив, причем если на одном уровне будет несколько одинаковых нод, он вернет их подмассивом с числовыми индексами.

    public function xmlReader2assoc($xml, $name) {
            $tree = null;
    
            while ($xml->read()) {
                if ($xml->nodeType == XMLReader::END_ELEMENT) {
                    return $tree;
                } else if ($xml->nodeType == XMLReader::ELEMENT) {
                    if ((!$xml->isEmptyElement)) {
                        $childs = $this->xmlReader2assoc($xml, $xml->localName);
    
                        if (count($childs) > 1) {
                            if (isset($tree[$xml->localName])) {
                                if (!isset($tree[$xml->localName][0])) {
                                    $moved = $tree[$xml->localName];
                                    unset($tree[$xml->localName]);
                                    $tree[$xml->localName][0] = $moved;
                                }
                                $tree[$xml->localName][] = $childs;
                            } else {
                                $tree[$xml->localName] = $childs;
                            }
                        } else {
                            $tree[$xml->localName] = $childs;
                        }
                    }
                } else if ($xml->nodeType == XMLReader::TEXT) {
                    $tree = $xml->value;
                }
            }
            return $tree;
        }
    Ответ написан
    Комментировать