• Покритикуйте код! Какие грубые и негрубые ошибки совершил?

    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 комментария
  • PHPStorm при плохом VPN соединении?

    GavriKos
    @GavriKos
    Поменять полностью стратегию деплоя. Разрабатывайте ПОЛНОСТЬЮ локально, удаленно разворачивайте через CI и гит.
    Ответ написан
    2 комментария
  • Как открывать пользовательские приложения с правами sudo?

    CityCat4
    @CityCat4
    //COPY01 EXEC PGM=IEBGENER
    Работать от рута - зло.

    Сделайте так:
    sudo chown -R alexey:alexey /home/alexey
    это исправит права на все файлы, которые рут успел насоздавать
    Ответ написан
    Комментировать
  • Какой ИБП выбрать для слабого офисного ПК, чтобы работал без света?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Комментировать
  • Какой ИБП выбрать для слабого офисного ПК, чтобы работал без света?

    @kamenyuga
    У бесперебойников в общем-то две основные характеристики - максимальная мощность и емкость батареи. Мощность - ее прямо в названии в магазинах пишут. Ее должно хватать для типичного потребления компьютера. Для описанных в вопросе пк скорее всего и 300 Вт будет всегда хватать. Можно брать любой самый дешевый. А батарея - тут зависит от необходимого времени работы автономной. Почти любого ИБП хватит, чтобы нормально выключить компьютер. А если надо прямо проработать какое-то время, то гуглим "nix время автономной работы ИБП при нагрузке" и получаем список из протестированных ибп вместе с ценами.
    Ответ написан
    1 комментарий
  • Комплектующие для игрового ПК, какие лучше?

    @Adrianus
    Ex nihilo nihil fit
    Водянку не советую - сдохнет помпа и под замену, хорошо если не вырвет и не зальет всё. У самого стоит Dark Rock 4 Pro на процессоре - идеален.

    Настолько топовое железо в примере....а смысл? У меня, например, Intel i7-4820K (LGA2011), ASUS X79 Deluxe, 16 Gb оперативки и видеокарта Gigabyte GeForce1660 Super. "Киберпанк" и все топовые шутеры идут на полных и без багов. По ФПС не подскажу, правда.
    Ответ написан
    1 комментарий
  • Комплектующие для игрового ПК, какие лучше?

    xez
    @xez Куратор тега Компьютеры
    TL Junior Roo
    У меня несколько вопросов:
    1. Точно ли нужен 5900x? Может хватит 5800x или даже 5600x ?
    2. Зачем водянка? Как по мне, лучше топовый воздух.
    3. Самое главное. Вот вы выбираете mb + ram... Ну есть же QVL для вашей матери.. Почему не выбрать память из того списка?
    Ответ написан
  • Как сайту на кириллическом домене отправлять почту?

    profesor08
    @profesor08
    1. Не использовать кириллические доменные имена
    2. В случае проблем смотреть первый пункт
    Ответ написан
    Комментировать
  • Как реализовать SMTP отправку почты PHP?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Поскольку вы не дожидаетесь ответа сервера, то ваши команды уходят на сервер до того, как он будет готов их принять.
    Ответ написан
    Комментировать
  • Как понять есть ли нагрузка на БД?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Почему больше всего подписчиков всегда слетается на самые дурацкие вопросы?
    Которым место в мусорке, а не на главной Хабра.
    Ну ведь как в прошлый раз же, весь текст - какие-то бессвязные эротические фантазии, не имеющие ничего общего ни с реальностью, ни друг с другом, ни - главное - с собственно вопросом, который был задан.

    Так вот: я смотрю, что получил 1500 строк из базы за 0.0316 секунд. Это нормально?

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

    База растёт и строк к выводу станет больше.

    С КАКОГО, я стесняюсь спросить, перепугу, с ростом базы строк к выводу станет больше?
    На тостере с каждым днем прибавляется сотня дебильных вопросов.
    Ты уверен что количество запрашиваемых из базы строк тоже растёт? А если подумать? А если прям вот хорошенько подумать?

    Этот ход мысли напоминает старый еврейский анекдот, который рассказывал Джоэл Спольский в далёком 2001 году:
    Маляр Шлёма подрядился красить пунктирные осевые линии на дорогах. В первый день он получил банку краски, поставил её на дорогу, и к концу дня покрасил 300 метров осевой линии. «Отлично! — сказал прораб. — Быстро работаешь!» и заплатил ему.
    На следующий день Шлёма покрасил 150 метров. «Мда, это, конечно, не так здорово, как вчера, но приемлемо», — сказал прораб и снова заплатил ему.
    Ещё через день Шлёма покрасил всего 30 метров. «Всего лишь 30! — заорал прораб. — Это никуда не годится! В первый день было в десять раз больше! В чём дело?»

    «Ничего не могу поделать, — говорит Шлемиэль. — Каждый день я ухожу всё дальше и дальше от банки!»


    Тебе не кажется что эта логика напоминает твоё "но с каждым днём в БД появляется всё больше и больше записей!"?

    На что ориентироваться? На показатели загрузки процессора или время выполнения запроса или расход памяти?

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

    И вопрос в догонку: если одним запросом я получаю 1500 строк и если в запросе я установлю select нужных мне столбиков - это усложняет запрос или нет? Ведь в первом случае я получаю информацию как есть, а во втором случае процессору надо время чтобы перебрать нужные столбики?!

    Судя по количеству восклицательных знаков - это самый важный вопрос во всём этом и так целиком гениальном тексте. Процессор опасносте!!! Срочно надо спасать!

    Запрос выполняется три сотых секунды, дом рисуется 10, но вопрос почему-то "как узнать , не тормозит ли база?"
    Ну ей-богу, снова как в анекдоте - "Где логика??! Где разум??".

    Сейчас я кеширую результаты php на 60 минут,

    Вот это я понимаю. Сразу заходим с козырей.
    странно что на 60 минут, а не на 24 часа. или вообще сделать сайт статикой. тогда вообще всё летать будет. Или вообще перенести всю БД на клиента. Чего не сделаешь ради борьбы за миллисекунды.

    Как понять есть ли нагрузка на БД?/

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

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

    И тогда и твоя микроскопическая БД в 10 тыщ записей, и нормальная база с миллионами строк, будут работать одинаково быстро и эффективно.
    Ответ написан
    8 комментариев
  • Как с помощью jquery получить числовое значение тега?

    v3shin
    @v3shin
    Веб-шаман
    let x = $('td:nth-child(3)').eq(0).text();
    x = +x.replace(/[^0-9.]/g, '');
    // теперь x - число
    Ответ написан
    Комментировать
  • Защита на js от рипла дизайна сайта?

    @alekcena
    Нелинейный наставник
    Никак. (Странно что вы знаете о существовании).
    Когда вы загружаете страницу вы по факту устанавливаете на локальное устройство все файлы для отображения этого сайта.
    Дело в понимании как работает "Интернет"
    Ответ написан
    2 комментария
  • Где есть годные БЕСПЛАТНЫЕ уроки для vue.js?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Ответ написан
    Комментировать
  • Почему сбрасывается ob_start()?

    Adamos
    @Adamos
    Битрикс буферизирует все сам. С момента подключения header и по самый footer. Вот вы с ним и конфликтуете.
    Ответ написан
    Комментировать
  • Как подключать less и sass файлы?

    profesor08
    @profesor08
    Такая информация отображается если настроить правильно sourcemaps.
    Ответ написан
    Комментировать
  • Какие еще преимущества у юнит-тестов, кроме того, что они отлично обеспечивают регрессионное тестирование?

    Писать тесты может джун, это правда. Понимать что и как тестировать — это бывает и для опытного человека сложно.

    Описанные недостатки — очень спорные. Метод пристального взгляда находит баги только в первые 10 минут, пока голова свежая.

    Но да, с тем, что автотестами нужно покрывать не всё, я лично полностью согласен. Вдобавок, часто высокоуровневые функциональные или end-to-end тесты писать проще, а для проекта они полезнее. Тут надо искать баланс для себя. И еще в это уравнение добавить ручное тестирование. Какой-то общей формулы, понятно, нет.

    А вопрос-то ваш в чём? Пока выглядит как «вы тут меня поуговаривайте писать тесты, а я вам буду объяснять, почему не буду этого делать». Не хотите — не пишите. Если для вашего проекта и для вашей команды тесты не несут большой пользы, то и не пишите их.
    Судя по вашим прошлым вопросам, вы считаете, что всё знаете лучше других, соответственно, вопрос нужен, чтобы потешить ЧСВ? Ну или вы нарвались на какой-то карго-культ-секты-стопроцентного-кавереджа? В таком случае — сочувствую.
    Ответ написан
  • Какие есть принятые названия для классов CSS?

    firedragon
    @firedragon
    Не джун-мидл-сеньор, а трус-балбес-бывалый.
    Учите английский. Все эти названия тупо значат то чем они являются. Просто забейте в переводчик.
    вот вам для начала
    https://material.io/components?platform=web
    еще от мелкомягких
    https://developer.microsoft.com/ru-ru/fluentui#/co...

    На самом деле их куча этих руководств
    Ответ написан
    Комментировать
  • Как ограничить выполнение функции mousemove 1 раз в секунду?

    wapster92
    @wapster92 Куратор тега JavaScript
    Комментировать
  • Какой выбрать 3D принтер?

    @evgeniy_lm
    3D-принтер для дома. Нужен не DIY, а готовый. Без лишних заморочек. Бюджет до 50 тыс. Р.

    Слишком много противоречий в связи с не пониманием ситуации.
    Разницы между DIY и "готовый" в указанном вами ценовом диапазоне нет, это один и тот же принтер только в первом случае его собрали вы, а в другом кто-то за вас и, разумеется, вы ему хорошо заплатили (45-60% от потраченной суммы).
    Увы, пока еще 3D-принтер в корне отличается от, например, 2D-принтера. К сожалению формула "купи и печатай" здесь не работает, "заморочек" вас ждет вагон и, как минимум, пара маленьких тележек. Без заморочек лучше заказать печать у соседского пацана

    ЗЫ "Закрытую камеру" лучше купить отдельно в виде подходящего шкафчика, это будет существенно дешевле. Шкаф какой нужно можно заказать в ближайшей мебельной мастерской.
    ЗЫ
    Ответ написан
    Комментировать
  • Как правильно документировать rest api?

    yarkov
    @yarkov
    Помог ответ? Отметь решением.
    OpenAPI, Swagger
    Ответ написан
    Комментировать