Подключение к базе данных происходит вот так: Код (Text): $db = mysqli_connect(BD_HOST, BD_LOG, BD_PASS, BD_NAME) or die('Ошибка подключения к БД'); Потом в теле файла имеется несколько запросов к базе; все нормально работает. Но еще есть функция вывода комментариев. Она очень громоздкая, и приводить ее полностью нет смысла. Проблема в том, что в эту функцию я хочу добавить запрос к базе, и возникает проблема. Код (Text): function comments(array $comments, $level = 0, $next = 0, $arr = array()) { // Здесь всякие логические операции без обращения к базе. // А это мой запрос к базе query = mysqli_query($db, "SELECT `id` FROM `comment` WHERE `id` = 157"); } comments($comments); Диагностическое сообщение: <b>Notice</b>: Undefined variable: db in <b>/home/b/comment-text.php</b> on line <b>94</b><br /> <br /> <b>Warning</b>: mysqli_query() expects parameter 1 to be mysqli, null given in <b>/home/b/comment-text.php</b> on line <b>94</b><br /> 94 - это и есть строка моего запроса. Я понимаю, что $db не попадает в область видимости переменных функции. А как её туда "запихнуть"?
Подключил через параметры функции. Это нормально? Код (Text): function comments($db, array $comments, $level = 0, $next = 0, $arr = array()) comments($db, $comments);
@Vladd55, даже если получится (почему сам не попробовал?), это жёсткое извращение, сессии не для этого.
Конечно же, я попробовал. Но я исхожу из того, что не все, что заработало, правомерно использовать. Поэтому нетиповые ситуации уточняю. А global/$GLOBALS мне как-то сильно не по вкусу. Других же штатных вариантов нет?
Обернуть в класс, в конструкторе задать свойство $db, из других методов обращаться к нему, если чуть менее сложно. И да, с глобальной областью видимости вообще экспериментировать плохо.
Как выше написали, для процедурки норм. предопределенные глоб. переменные. (НЕ «предопределенные», т.е. переменные для собвенных нужд фронта, тоже норм.) Ну, если сильно хоЦА, можешь загнать в какой-нить синглтон, общую переменную реестра или какую-нибудь спец. переменную (чтобы к ней обращаться через спец. ф-цию вроде db()). В G-Drive, например, использовали глоб. переменную $link (она считается параметром контроллера; потом ее можно самому куда-нить загнать под соотв. модель и т.п., если надо). В более «взрослых» фронтах – соответственно более «взрослые» подходы. --- Добавлено --- Для моделей на процедурке там обычно так: контроллер вызывает ф-цию модели без передачи $link, та библиотечную ф-цию для работы с БД без передачи $link, а библиотечная ф-ция обращается напрямую к global $link. --- Добавлено --- Еще иногда у ф-ций моделей и библиотечных ф-ций для работы с БД бывает дефолтный параметр $link='link', чтобы можно было делать так: $GLOBALS[$link] (не путать с $GLOBALS['link']). Но по-моему это изврат. Проще значение глоб. переменной подменять, если нужно работать сразу с несколькими объектами mysqli. --- Добавлено --- Нет никакой обработки ошибок? Ф-ции-обертки для работы с БД используются не просто, как абстрактный слой, а еще и исключения при ошибках генерируют Это тоже фигня. Нужно 503-юю выдавать И еще вот что: https://gency.ru/comment/116 (кодировку можно не хардкодить, а тоже из конфиг. параметра брать).
Не надо ничего запихивать. Измените общий подход, разбив скрипт пошагово. У вас есть: подключение к базе, составление запроса к ней, и обработка вывода. Ни один из шагов не требует запихивания.
Автору. Напишите или подключите готовый движок работы с базой. Сможете тогда юзать его где угодно на сайте.
@Vlad55 Можно написать функцию или статический метод класса, которая/ый будет возвращать соединение с базой. В отличие от переменных, функции тебе доступны в любом месте. Еще тебе в копилку — переменные, объявленные со словом static, сохраняются в последующих вызовах. PHP: function db() { static $db = null; return $db ?? $db = mysqli_connect(...); // функция будет вызвана только один раз! } // ... $result = mysqli_query(db(), "SELECT ..."); Как временное решение потянет. Постепенно ты придешь к пониманию что процедурный подход неудобен, начнешь использовать классы, и будешь инжектить все нужные зависимости. --- Добавлено --- https://www.php.net/manual/ru/language.variables.scope.php#language.variables.scope.static
Так как в PHP объекты не долго живут, удобнее использовать статические методы и переменные класса. Их так же удобно вызывать как и функции, и не нужны глобальные переменные для хранения подключения к базе данных. PHP: class DB { private static $con = null; private static function con() { if (! self::$con) { self::$con = mysqli_connect(...); } return self::$con; } static function query($sql) { return mysqli_query(self::con(), $sql); } } $comment = DB::query("SELECT `id` FROM `comment` WHERE `id` = 157"); Плюс такого подхода ещё и в том, что подключение к базе данных происходит лишь при первом SQL-запросе, а если запросов не было при вызове какой-нибудь страницы, то и не будет впустую подключаться к базе данных. Вместо mysqli посмотри на использование PDO, работающий одинаково с разными базами данных, и где можно безопасно и удобно передавать параметры в SQL, что-то вроде такого: PHP: $comment = DB::query("SELECT * FROM comment WHERE id=?", [$id]);
Повставляй логгирование в деструкторы и удивись ))) Да и вообще, если есть класс App, в котором всё запускается, живут все замечательно.