Задать вопрос
  • Почему мобильные приложения так велики?

    VoidVolker
    @VoidVolker
    Dark side eye. А у нас печеньки! А у вас?
    Абсолютное большинство таких приложений — это браузерные приложения, причём вместе с браузерным движком внутри, который тянет за собой ещё кучу всего. Ну и никто особо не занимается оптимизацией размеров из-за использования больших фреймворков с кучей функций, библиотек, а так же множеством других зависимостей, большая часть из которых даже не используется. Десяток или сотня мегабайт ради одной простой функции? Запросто. Плюс зоопарк разных версий ОС, где нужные разные версии каких-то библиотек. Изображения, анимации, видео и прочее — тоже занимают кучу места. В процессе жизненного цикла приложения меняются разработчики и руководители, которые не особо понимают изначально запланированный путь развития приложения или ситуация меняется и надо делать по-другому, а ещё прилепляются дикие фантазии руководителей и маркетологов. А чаще вообще нет никакого плана и просто делают как получится. И в итоге получается дикая каша из кучи разнородных экранов, фреймов, элементов интерфейса, запутанной логики переходов, сотен и тысяч библиотек, а бывает что даже и нескольких разных версий одной и той же библиотеки. К сожалению, идея впихивать в одно приложение огромную кучу разных функций появилась не сегодня и все эти комбайны существуют уже давно.
    Ответ написан
    2 комментария
  • Вычисления datetime if()?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    $now = new DateTimeImmutable();
    var_dump(new DateTimeImmutable('2024-05-20 12:45:53') < $now);
    // bool(true)
    Ответ написан
    1 комментарий
  • Почему ajax выполняется по очереди?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Вангую - на бэке PHP и сессии. Причём, открываются сессии в начале скрипта, а закрываются никогда, то есть по завершении скрипта.
    Тогда пока работает скрипт, файл сессии держится открытым и второй скрипт в той же сессии будет ждать освобождения файла. Файл сессии надо освобождать как можно раньше. session_start, считали нужные данные и сразу же session_write_close. Если надо что-то изменить в сессионных данных в процессе работы скрипта, то снова открыть сессию, записать изменения, закрыть.
    Ответ написан
    Комментировать
  • Подсчёт в бд по возрастанию?

    Vapaamies
    @Vapaamies
    Психанул и снес свои ответы не отмечающим решения…
    Зависит от СУБД, но в целом как-то так: order by cast(place as number).
    Ответ написан
    7 комментариев
  • Как решить проблему с php?

    @alexalexes
    Во-первых, нужно узнать, где находиться файл error_log, куда сервер пишет ошибки.
    Во-вторых, в любой непонятной ситуации добавляем в начале скрипта принудительное рапортование ошибок в лог и вывод их пользователю в начале скрипта:
    <?php
    error_reporting(E_ALL); // репорт ошибок в файл error_log
    ini_set('display_errors', 'On'); // вывод сообщения об ошибке

    В-третьих, не стесняемся пользоваться функцией var_dump/print_r для любых переменных, где есть сомнения, что они содержат нужные значения.
    var_dump($_POST);
    В-четвертых, при изучении любой библиотеки взаимодействия с СУБД первым делом лезем в справку и ищем, как вывести человекочитаемые ошибки. В PDO это метод errorInfo. Применяем его после любой операции с СУБД - коннектом, подготовкой запроса, выполнением запроса, выборкой результата:
    var_dump($pdo->errorInfo());
    В-пятых, в браузере F12, вкладка "Сеть". Смотрим, а на тот ли адрес идет запрос отправки формы. Изучаем HTTP заголовки, полезную нагрузку, ответ от сервера.

    Вот пример базовых навыков PHP разработчика. Без них можно даже не открывать видосики.
    Ответ написан
    2 комментария
  • Можно ли корректно заполнить создаваемое поле таблицы данными из другой таблицы?

    Adamos
    @Adamos
    UPDATE TableA LEFT JOIN (
    SELECT MIN(Id) AS id, Name FROM TableB GROUP BY Name
    ) AS b
    ON TableA.Name = b.Name
    SET TableA.TableBId = b.id

    Соотвественно, до этого запроса - ALTER TABLE с добавлением столбца TableBId, после - ALTER TABLE с удалением Name.
    Можно сделать "ногой в дверь", записывая значение прямо в Name и потом ALTER TABLE его с переименованием и сменой типа, но я бы не рисковал ;)
    Ответ написан
    3 комментария
  • Как правильно составить данный запрос?

    iMedved2009
    @iMedved2009
    Не люблю людей
    Тогда у вас какая то странная структура.

    наверное вам надо как-то так

    https://sqlize.online/sql/mariadb/ed3f54e80ceedc7d...
    select 
      users.id, users.name, group_concat(country.country) as visited 
    from 
      users
    left join user_to_country on user_to_country.user_id = users.id
    left join country on user_to_country.country_id = country.id
    where u_status = 1 
    group by users.id, users.name;
    Ответ написан
    1 комментарий
  • Как использовать сканер штрихкодов в вебе?

    @accountnujen
    сканер штрихкодов - это клавиатура. дружить её ни с кем не надо. Просто нужно добавить обработчик на ввод текста.

    Из коробки сканер штрихкодов печатает текст и жмёт enter (хотя не все не то что модели, иногда даже ревизии не жмут enter из коробки)

    https://learn.javascript.ru/keyboard-events
    Ответ написан
    8 комментариев
  • Как называется плагин для vs code?

    Комментировать
  • Как добавить данные в БД через HTML-форму?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Сначала учимся правильно соединяться.
    В случае mysqli это
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $link = mysqli_connect($host, $user, $pass, $db_name);
    $link->set_charset("utf8mb4");

    И никаких ужасов с "Соединение не установлено" тут быть не должно.

    После этого выполняем запрос INSERT. Причем запросы мы всегда пишем так, чтобы данные в БД попадали отдельно от самого запроса. Это непреложное правило, которое надо соблюдать всегда.
    Для этого надо
    • Заменить все переменные в запросе на специальные маркеры, которые называются плейсхолдеры или параметры, а по сути - просто знаки вопроса
    • Подготовить запрос к исполнению с помощью функции prepare(). Эта функция принимает строку запроса и возвращает экземпляр специального класса stmt, с которым в дальнейшем и производятся все манипуляции
    • Привязать переменные к запросу.
    • Выполнить подготовленный ранее запрос с помощью с помощью execute()

    В mysqli это будет так
    $sql = "INSERT INTO `events` (`title`, `discription`, `date`, `img`) VALUES (?,?,?,?)";
    $stmt = $link->prepare($sql);
    $stmt->bind_param("sssss", $title, $discription, $date, $path);
    $stmt->execute();

    bind_param() принимает в качестве параметров все переменные, которые должны попасть в запрос, в том же самом порядке, в котором стоят плейсхолдеры в запросе. Но кроме того, сначала в этой функции должны быть указаны типы для всех переменных, в виде строки, где тип переменной обозначается одной буквой. То есть букв в этой строке должно быть ровно столько, сколько дальше будет переменных. К счастью, можно особо не париться с типами и для всех переменных указывать тип "s".

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

    Весь код, который добавляет запись в БД, должен быть расположен ДО любого вывода.
    После обработки запроса методом POST необходимо перенаправить клиента куда-нибудь методом GET и завершить работу скрипта. Делается это функцией header с заголовком location: . после которой написать exit;
    Соответственно, никаких ужасов с "Запись добавлена".

    Кстати, немного удобнее с БД работать не через mysqli, а чрез PDO, Тем более что там колупаться с bind_param не нужно, а можно сразу отправить все данные в execute

    Подключение
    $host = '127.0.0.1';
    $db   = 'test';
    $user = 'root';
    $pass = '';
    $port = "3306";
    $charset = 'utf8mb4';
    $options = [
        \PDO::ATTR_ERRMODE            => \PDO::ERRMODE_EXCEPTION,
        \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
        \PDO::ATTR_EMULATE_PREPARES   => false,
    ];
    $dsn = "mysql:host=$host;dbname=$db;charset=$charset;port=$port";
    $pdo = new \PDO($dsn, $user, $pass, $options);


    Выполнение запроса
    $sql = "INSERT INTO `events` (`title`, `discription`, `date`, `img`) VALUES (?,?,?,?)";
    $stmt = $link->prepare($sql);
    $stmt->execute([$title, $discription, $date, $path]);
    Ответ написан
    1 комментарий
  • Как вставить данные в запрос?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    public $query - это неправильно с десятка разных точек зрения, от архитектуры до простой житейской логики.
    Но при этом, если бы данные в запрос передавались правильно, а не как как обычно, то чисто технически это бы сработало

    В любом случае, public $query убрать, вместо этого добавить private $db, и в конструктор, соответственно, такой же параметр
    public function addProduct(){
        $query = 'INSERT INTO products (title, price, description, category, image, active) VALUES (?,?,?,?,?,?)';
        $stmt = $this->db->prepare($query);
        $stmt->bind_param("ssssss", $this->title, $this->price, $this->description, $this->category, $this->image, $this->$active);
        $stmt->execute();
    }
    Ответ написан
  • Че он на элемент не нажимает?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Ну короче типа внатуре getElementsByClassName возвращает как бы коллекцию элементов, а у коллекции, мамой клянусь, свойства childNodes нет.

    По секрету, братиш, вот: document.querySelector('.case-print')

    Ну там ещё дальше click работать не будет, но это уж самостоятельно в виде домашнего задания.
    Ответ написан
    Комментировать
  • Стоит ли учить html, css,js в 2021?

    approximate_solution
    @approximate_solution
    JS Developer. Angular\React\Vue\Ember
    Просто актуальной инфы так мало по этому, а я вылез из 2015 года.

    У вас странные вопросы. HTML + CSS + JS это костяк всего веба который в принципе не заменим.

    Логически построим цепочку. Есть бизнес разного уровня - ИП, средний бизнес, интерпрайз.

    Wordpress Elementor и его аналоги, подходят для конкретной задачи - быстрое прототипирование интерфейса и запуск бизнеса в кратчайшие сроки. Пример: сегодня 1 марта, и до 8 марта вам нужно быстро запустить лендинг или магазин на шаблоне wp, что бы реализовать продажу цветов. Всё.

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

    Задача фронтендера - отлично знать HTML + CSS + JS + (React\Vue\Angular) + REST API + WebSocket + сборщики + препроцессоры + figma + performance + assesability - и да, всё это требования джуна.

    Умение грамотно строить скелет приложения не накинув лишних вложенностей + грамотно проектируя интерфейс компонентами - добавляет вам денег и профита в конце пути. Джуна без знаний html\css в принципе на работу не возьмут.
    Ответ написан
    Комментировать
  • Зачем так сделано?

    delphinpro
    @delphinpro Куратор тега CSS
    frontend developer
    Не использовать rgba в css, заменяя цвет картинкой – это только если нужно поддерживать IE8 и ниже. Тут или реально нужна такая поддержка, или верстка очень старая, или верстальщик отстал в развитии.

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

    Я бы даже ошибками это не назвал. Либо очень древнее легаси, либо некомпетентность исполнителя.
    Ответ написан
    2 комментария
  • Покритикуйте код! Какие грубые и негрубые ошибки совершил?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Ну тут скорее ни одной почти строчки нормальной.
    • exit('Ошибка подключения к базе данных!'); дважды глупость. Пользователю сайта не интересно читать, что у тебя сломалось - база данных или деньги на пиво кончились. Как программисту, тебе эта бессмысленная фраза тем более бесполезна, она ничего не говорит о том, ЧТО КОНКРЕТНО сломалось, чтобы ты мог исправить
    • if ($numRows > 0) { бессмысленный кусок кода
    • while ($row = $result->fetch_assoc()) { заменяется на $result->fetch_all(MYSQLI_ASSOC)
    • $this->connect() коннектимся каждый раз, чтобы выполнить запрос, серьёзно?
    • А когда будет еще один класс, для другой таблицы, снова будешь писать код подключения к БД? И так в каждом?
    • Почему класс для работы с "позициями" называется DBh?
    • По сути это не класс, а набор функций. Если ты уберешь красивые слова class и this, то НИЧЕГО не изменится
    • SQL инъекции кругом
    • class Handler extends Dbh ВООБЩЕ непонятно зачем



    В общем, как-то так
    dbh.php
    class Dbh
    {
        public $conn;
    
        public function __construct($config)
        {
            mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
            $this->conn = new mysqli(...$config);
            $this->conn->set_charset('utf8mb4');
        }
    
        public function preparedQuery($sql, $params, $types = '')
        {
            $types = $types ?: str_repeat('s', count($params));
            $stmt = $this->conn->prepare($sql);
            $stmt->bind_param($types, ...$params);
            $stmt->execute();
            return $stmt;
        }
    
        public function selectResult($sql, $params, $types = '')
        {
            if (!$params) {
                return $this->conn->query($sql);
            }
            return $this->preparedQuery($sql, $params, $types)->get_result();
        }
        public function selectAll($sql, $params = [], $types = '')
        {
            return $this->selectResult($sql, $params, $types)->fetch_all(MYSQLI_ASSOC);
        }
        public function selectAssoc($sql, $params = [], $types = '')
        {
            return $this->selectResult($sql, $params, $types)->fetch_assoc();
        }
        public function selectRow($sql, $params = [], $types = '')
        {
            return $this->selectResult($sql, $params, $types)->fetch_row();
        }
        public function selectCell($sql, $params = [], $types = '')
        {
            $row = $this->selectRow($sql, $params, $types);
            return $row ? $row[0] : false;
        }
    }

    position.php
    class Position
    {
        protected $dbh;
    
        public function __construct(Dbh $dbh)
        {
            $this->dbh = $dbh;
        }
        // Получаем все позциии из БД и возвращаем их в массиве $output если записей больше нуля
        public function getAllPositions()
        {
            return $this->dbh->selectAll('SELECT * FROM positions');
        }
        protected function addPosition($content)
        {
            $count = $this->dbh->selectCell('SELECT count(*) FROM positions');
            if ($count < 10) {
                $this->dbh->preparedQuery("INSERT INTO positions (content) VALUES (?)", [$content]);
            }
        }
        protected function deletePosition($id)
        {
            $this->dbh->preparedQuery("DELETE FROM positions WHERE id = ?", [$id]);
        }
        //Поиск позиций в БД по столбцу content
        protected function searchPosition($content)
        {
            $content = "%$content%";
            return $this->dbh->selectAll('SELECT * FROM positions WHERE content LIKE ?',[$content]);
        }
    }

    config.php
    return [
          'db' => [
              'host' => '127.0.0.1',
              'username' => '',
              'password' => '',
              'dbname' => '',
              'port' => 3306,
          ],
      ];


    handler.php

    $config = require 'config.php';
    $dbh = new Dbh($config['db']);
    $position = new Position($dbh);
    
    switch ($_GET['action']) {
        case 'getpositions':
            $output = $position->getAllPositions();
            echo json_encode($output);
            break;
        case 'addposition':
            $content = $_GET['content'];
            $position->addPosition($content);
            break;
        case 'getsearchpositions':
            $content = $_GET['content'];
            $output = $position->searchPosition($content);
            echo json_encode($output);
            break;
        case 'deleteposition':
            $id = $_GET['id'];
            $position->deletePosition($id);
            break;
        default:
            header("HTTP/1.0 400 Bad Request");
    }
    Ответ написан
    2 комментария
  • JQuerry стоит ли еще использовать, или однозначно нет?

    AntonLitvinenko
    @AntonLitvinenko
    HTML coder
    отказываются, экономят 90 кило, а потом начинается:
    а как плавно показать-убрать элемент?
    а посоветуйте плагин только чтобы под ванилку?
    а почему у меня не присваиваются классы (потому что забыли цикл, который в джейквери из коробки)
    мое имхо - джейквери живе всех живых, ради экономии 90 кило точно не вижу смысла - любая фотка которую забыли оптимизировать весит в разы больше
    Ответ написан
    Комментировать
  • Как сделать множественный update?

    rozhnev
    @rozhnev Куратор тега MySQL
    Fullstack programmer, DBA, медленно, дорого
    Ваш запрос работает корректно, хотя лучше использовать JOIN синтакс:
    UPDATE first_table
    JOIN second_table ON first_table.id = second_table.id
    SET first_table.count = first_table.count + second_table.total_count,  second_table.total_count = 0
    WHERE second_table.id = 1;


    MySQL fiddle here
    Ответ написан
    1 комментарий
  • Шрифты CSS - Как сделать особенную W?

    EPIDEMIASH
    @EPIDEMIASH
    Человек швейцарский нож
    Скачайте нормальный шрифт и будет вам счастье.

    606824d448dec858956606.jpeg
    Ответ написан
    1 комментарий
  • Как часто нужна модель MVC?

    Stalker_RED
    @Stalker_RED
    Да, это полезно - написать свой фреймворк и/или CMS.
    Потом полезно сравнить его с laravel или symfony, найти чем ваш фреймворк лучше.
    Если ничем не лучше - можете его смело забросить, и переходить на что-то общеизвестное, и вот почему:

    Представим, что у вас заказали лендинг по заказу насосов, например, и вы сделали его на своем фреймворке. Через 5 лет вы сменили род деятельности, и водите экскурсии по Тасмании. Или вас укусил радиоактивный паук, и теперь вы спасаете мир, а поддержкой сайтов не занимаетесь.

    Сервис с насосами за это время вырос, они теперь еще и бурят скважины, и фильтры устанавливают и колодцы копают, и у них филиалы в 20 городах. Им нужно доработать сайт. И при поиске разработчика выясняется, что сайт ваш доработать невозможно, т.к. документации по фреймворку нет, готовых модулей совместимых нет, интеграций с 1C, google docs, microsoft sharepoint нет, и никогда не будет. И проще переписать с нуля, чем разбираться как оно у вас там устроено.

    А если бы сайт был на общеизвестном фреймворке, то гораздо проще найти и специалистов и найти готовые интеграции.

    Никто не закажет сайт на самописном фреймворке если он планирует развитие своего бизнеса и понимает что он вообще делает. То есть ваши потенциальные клиенты - это только те, кто впервые заказывает себе сайт, и вы ему смогли впарить самоделку.
    Ответ написан
    4 комментария