Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Как заставить класс увидеть переменные в файле?

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (2): [1] 2 »   

> Без описания
ЧИМ
Отправлено: 27 Января, 2017 - 11:49:17
Post Id


Новичок


Покинул форум
Сообщений всего: 49
Дата рег-ции: Дек. 2016  


Помог: 0 раз(а)




Доброго времени суток.
Пытаюсь научиться применять классы, но что то не со всем выходит.
Грубо говоря, если я делаю класс на запись в файл данных, то и потом перед вызовом класса определяю переменные которые в нём задействованы, то всё нормально.
Класс для записи в файл:
CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. class write_connect {
  3.     public function __construct($host,$bd,$login,$passw,$file)
  4. {
  5.    
  6.     if (is_writable($file))
  7.         {
  8.         $fp= fopen($file, 'w');
  9.         $dt_con="<?php \n \$HOST='$host'; \n \$DB='$bd'; \n \$LOGIN='$login'; \n \$PASSW='$passw'; \n";
  10.        fwrite($fp, $dt_con);
  11.        
  12.        }
  13. else {
  14.            echo "Файл $file не доступен для записи!";
  15. }
  16. return;
  17. }
  18. }


Вызов класса:
CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. #считываем введённые данные подключения из POST
  3. $host=$_REQUEST['host'];
  4. $bd=$_REQUEST['bd'];
  5. $login=$_REQUEST['login'];
  6. $passw=$_REQUEST['passw'];
  7. $file='connect.php'; //Подключаем обработчик записи данных подключения в файл
  8. $write_file= new write_connect($host, $bd, $login, $passw, $file);
  9.  

Этот код работает исправно как я и хотел. Т.е. Есть форма мастера которая создаёт первоначальное подключение к БД и записывает его в файл connect.php.

А вот после этого необходимо из класса подключения к базе mysql увидеть переменные в этом файле и их значения.
Нашёл самый элементарный пример(на этом же форуме) и пытаюсь им воспользоваться, но с одной оговоркой, данные я хочу передать из файла который подключил через require_once 'connect.php'
Код класса:
CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. class bd {
  3.     public function __construct($H, $L, $P, $D)
  4.             {
  5.         mysqli_connect($H, $L, $P, $D);
  6.            }  
  7. }
  8.  
  9.  


Код работы с классом:
CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. $con=new bd($HOST, $LOGIN, $PASSW, $DB);
  3. if($con->connect_error)die ($con->connect_error);
  4. $con->set_charset("utf8");
  5.  


В итоге я вижу "Fatal error: Call to undefined method bd::set_charset() in ...\config\create_bd.php on line 16"

Подскажите как правильно подключить данные из файла для работы с классом? И правильно ли я вообще создал класс подключения к БД?
 
 Top
ЧИМ
Отправлено: 27 Января, 2017 - 14:24:18
Post Id


Новичок


Покинул форум
Сообщений всего: 49
Дата рег-ции: Дек. 2016  


Помог: 0 раз(а)




Нашёл всё таки самый простой класс и смог адаптировать его под себя.
CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. class SqlDB extends mysqli {
  3.     public function __construct($HOST,$LOGIN,$PASSW,$DB,$charset='utf8') {
  4.         parent::__construct($HOST,$LOGIN,$PASSW,$DB);
  5.         $this->set_charset($charset);
  6.         if (mysqli_connect_error()) {
  7.             die('Ошибка подключения (' . mysqli_connect_errno() . ') '
  8.                     . mysqli_connect_error());
  9.         }
  10.     }
  11. }
  12.  

Осталось теперь научиться наращивать в нём функционал для дальнейших манипуляций. Например сейчас думаю о том как внедрить проверку на защиту от SQL инъекций с помощью плейсхолдеров. В сети куча готовых примеров, но тупо вставить код и надеяться что он будет работать как мне нужно не понимая сути написанного не хотелось бы. По этому хотел бы узнать, может кто кинет ссылкой(на русском) где разжёвано как правильно составлять плейсхолдеры?
 
 Top
ЧИМ
Отправлено: 06 Февраля, 2017 - 12:05:54
Post Id


Новичок


Покинул форум
Сообщений всего: 49
Дата рег-ции: Дек. 2016  


Помог: 0 раз(а)




А как теперь в этот класс подключить файл connect.php? Чтоб не загружать 2 файла по отдельности, а загрузить один класс который будет подключаться к БД используя файл настроек.
 
 Top
Строитель Модератор
Отправлено: 16 Февраля, 2017 - 19:16:57
Post Id



Участник


Покинул форум
Сообщений всего: 1580
Дата рег-ции: Февр. 2014  
Откуда: Украина


Помог: 73 раз(а)




ЧИМ пишет:
А как теперь в этот класс подключить файл connect.php? Чтоб не загружать 2 файла по отдельности, а загрузить один класс который будет подключаться к БД используя файл настроек.
Можно передать ссылку на файл в конструктор дочернего класса, в дочернем конструкторе произвести подключение этого файла, и после этого вызывать родительский конструктор, в который и передавать данные для соединения с БД
PHP:
скопировать код в буфер обмена
  1. class SqlDB extends mysqli
  2. {
  3.     public function __construct($file)
  4.     {
  5.         require (file_exists($file) ? $file : '');
  6.        
  7.         $HOST  = isset($HOST) ? $HOST : '';
  8.         $LOGIN = isset($LOGIN) ? $LOGIN : '';
  9.         $PASSW = isset($PASSW) ? $PASSW : '';
  10.         $DB    = isset($DB) ? $DB : '';
  11.        
  12.         parent::__construct($HOST, $LOGIN, $PASSW, $DB);
  13.        
  14.         $this->set_charset('utf-8');
  15.        
  16.         if (mysqli_connect_error()) {
  17.             die ('Ошибка подключения ('. mysqli_connect_errno() .') '
  18.                 . mysqli_connect_error());
  19.         }
  20.     }
  21. }
  22.  
  23.  
  24. $sql = new SqlDB('connect.php');
 
 Top
ЧИМ
Отправлено: 17 Февраля, 2017 - 08:44:02
Post Id


Новичок


Покинул форум
Сообщений всего: 49
Дата рег-ции: Дек. 2016  


Помог: 0 раз(а)




Большое спасибо! Всё сработало! Единственное подправил строчку с определением наличия файла.
CODE (htmlphp):
скопировать код в буфер обмена
  1. require (file_exists($file) ? $file : '');

Изменил её на:
CODE (htmlphp):
скопировать код в буфер обмена
  1. require(isset($file) ? $file : '');

Потому как она постоянно говорила о том что такого файла нет и что имя файла не может быть пустым. Параметры передавал так же как и в isset. Но в isset всё заработало с этими же параметрами.
Потом перебрав все страницы и исправив везде код для создания класса, я понял что это не совсем удобно, так как в каждом файле нужно прописывать путь подключения файла, а в некоторых из них он разнится, из этого следует что может рано или поздно произойти путаница не будет доступа к файлу. В общем я решил что единственно правильным решением будет сделать единственное подключение в классе создания подключения. Теперь у меня класс выглядит так:
PHP:
скопировать код в буфер обмена
  1.  
  2. class SqlDB extends mysqli {
  3.     public function __construct() {
  4.         require_once '/config/connect.php';
  5.         $HOST  = isset($HOST) ? $HOST : '';
  6.         $LOGIN = isset($LOGIN) ? $LOGIN : '';
  7.         $PASSW = isset($PASSW) ? $PASSW : '';
  8.         $DB    = isset($DB) ? $DB : '';
  9.         $charset    = isset($charset) ? $charset : '';
  10.         parent::__construct($HOST,$LOGIN,$PASSW,$DB);
  11.         $this->set_charset($charset);
  12.         if (mysqli_connect_error()) {
  13.             die('Ошибка подключения (' . mysqli_connect_errno() . ') '
  14.                     . mysqli_connect_error());
  15.         }
  16.         $this->query('USE '.$DB.';');        
  17.     }
  18. }
  19.  

Подскажите, может какие советы будут ещё по этому классу? Здесь я не проверяю на предмет существования файла, так как уверен в его существовании и прописываю его в одном месте.
Создание нового подключения теперь происходит так:

(Отредактировано автором: 17 Февраля, 2017 - 08:46:49)

 
 Top
armancho7777777 Супермодератор
Отправлено: 17 Февраля, 2017 - 09:27:08
Post Id



Активный участник


Покинул форум
Сообщений всего: 4526
Дата рег-ции: Февр. 2011  
Откуда: Москва


Помог: 221 раз(а)




PHP:
скопировать код в буфер обмена
  1.  
  2. // File: /path/to/config/db/my_database.php
  3.  
  4. return [
  5.     'host'      => 'localhost',
  6.     'user_name' => 'dendy',
  7.     'password'  => '12345',
  8.     'charset'   => 'utf8'
  9. ];


PHP:
скопировать код в буфер обмена
  1. mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
  2.  
  3. /**
  4.  * @param string $dbName
  5.  * @return mysqli
  6.  * @throws mysqli_sql_exception
  7.  */
  8. function conn($dbName)
  9. {
  10.     static $conns = [];
  11.  
  12.     if(!isset($conns[$dbName])) {
  13.         extract(require("/path/to/config/db/{$dbName}.php"));
  14.         $conns[$dbName] = new mysqli($host, $user_name, $password, $dbName);
  15.         $conns[$dbName]->set_charset($charset);
  16.     }
  17.  
  18.     return $conns[$dbName];
  19. }
  20.  
  21. function myDatabase() {
  22.     return conn('my_database');
  23. }
  24.  
  25. try {
  26.     $conn = myDatabase();
  27. } catch(mysqli_sql_exception $e) {
  28.     echo 'Error: ', $e->getMessage();
  29. }
  30.  
 
 Top
Строитель Модератор
Отправлено: 17 Февраля, 2017 - 22:33:49
Post Id



Участник


Покинул форум
Сообщений всего: 1580
Дата рег-ции: Февр. 2014  
Откуда: Украина


Помог: 73 раз(а)




armancho7777777, если не ошибаюсь, у вас в строке №15 ошибка :

$conns[$dbName]->set_charset($config['charset']);

Вместо $config['charset'] нужна переменная $charset. Верно?
PHP:
скопировать код в буфер обмена
  1. $conns[$dbName]->set_charset($charset);
 
 Top
armancho7777777 Супермодератор
Отправлено: 18 Февраля, 2017 - 05:11:03
Post Id



Активный участник


Покинул форум
Сообщений всего: 4526
Дата рег-ции: Февр. 2011  
Откуда: Москва


Помог: 221 раз(а)




Да, верно. Спасибо. Поправил.
 
 Top
ЧИМ
Отправлено: 18 Февраля, 2017 - 21:30:22
Post Id


Новичок


Покинул форум
Сообщений всего: 49
Дата рег-ции: Дек. 2016  


Помог: 0 раз(а)




armancho7777777 пишет:
PHP:
скопировать код в буфер обмена
  1.  
  2. // File: /path/to/config/db/my_database.php
  3.  
  4. return [
  5.     'host'      => 'localhost',
  6.     'user_name' => 'dendy',
  7.     'password'  => '12345',
  8.     'charset'   => 'utf8'
  9. ];


PHP:
скопировать код в буфер обмена
  1. mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
  2.  
  3. /**
  4.  * @param string $dbName
  5.  * @return mysqli
  6.  * @throws mysqli_sql_exception
  7.  */
  8. function conn($dbName)
  9. {
  10.     static $conns = [];
  11.  
  12.     if(!isset($conns[$dbName])) {
  13.         extract(require("/path/to/config/db/{$dbName}.php"));
  14.         $conns[$dbName] = new mysqli($host, $user_name, $password, $dbName);
  15.         $conns[$dbName]->set_charset($charset);
  16.     }
  17.  
  18.     return $conns[$dbName];
  19. }
  20.  
  21. function myDatabase() {
  22.     return conn('my_database');
  23. }
  24.  
  25. try {
  26.     $conn = myDatabase();
  27. } catch(mysqli_sql_exception $e) {
  28.     echo 'Error: ', $e->getMessage();
  29. }
  30.  


Поправьте меня если я неправильно понимаю.

Здесь мы создаём в файле массив с переменными:
PHP:
скопировать код в буфер обмена
  1. return [
  2.     'host'      => 'localhost',
  3.     'user_name' => 'dendy',
  4.     'password'  => '12345',
  5.     'charset'   => 'utf8'
  6. ];


//Включаем расширенные сообщения по ошибкам:
PHP:
скопировать код в буфер обмена
  1. mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);


//Эта функция вытаскивает значения из файла
PHP:
скопировать код в буфер обмена
  1. function conn($dbName)
  2. {
  3.     static $conns = []; - //[b]Создаём статическую переменную[/b]
  4.  
  5.     if(!isset($conns[$dbName])) { //[b]Проверяем на существование переменной базы[/b]
  6.         extract(require("/path/to/config/db/{$dbName}.php")); //[b]Извлекаем переменные из файла[/b]
  7.         $conns[$dbName] = new mysqli($host, $user_name, $password, $dbName); [b]Создаём подключение[/b]
  8.         $conns[$dbName]->set_charset($charset);//[b] Кодировка[/b]
  9.     }
  10.  
  11.     return $conns[$dbName]; //[b] Возвращаем подключение[/b]
  12. }


PHP:
скопировать код в буфер обмена
  1. function myDatabase() {
  2.     return conn('my_database');//[b]Просто возвращаем имя базы?[/b]
  3. }


Вот это для меня вообще непонятно, это всё в классе? Т.е. Мы обрабатываем исключение вызова функции myDatabase() Если там есть ошибка то выводим её на экран?
PHP:
скопировать код в буфер обмена
  1. try {
  2.     $conn = myDatabase();
  3. } catch(mysqli_sql_exception $e) {
  4.     echo 'Error: ', $e->getMessage();
  5. }


Первый раз просто сталкиваюсь с использованием extract и по этому многие моменты непонятны. Например, почему мы объявляем постоянный массив "static $conns = [];" и сразу проверяем существует ли в нём "$dbName"? Как до if(!isset($conns[$dbName])) в нём появится значение $dbName? Так же мне непонятно, почему мы присваиваем значению массива подключение к базе? "$conns[$dbName] = new mysqli($host, $user_name, $password, $dbName); "
Чёт какой то бардак в голове от данного примера. Может я конечно туплю, но я был бы очень признателен если бы вы растолковали что к чему.
 
 Top
Строитель Модератор
Отправлено: 18 Февраля, 2017 - 21:50:57
Post Id



Участник


Покинул форум
Сообщений всего: 1580
Дата рег-ции: Февр. 2014  
Откуда: Украина


Помог: 73 раз(а)




ЧИМ пишет:
Поправьте меня если я неправильно понимаю.
Елси не возражаете, я дам пояснения:
ЧИМ пишет:
Здесь мы создаём в файле массив с переменными
Ассоциативный массив значений - так корректнее.
ЧИМ пишет:
Просто возвращаем имя базы?
Нет, возвращается объект mysqli (если в процедурном - то это был бы тип "ресурс"), с которым вы будет производить дальнейшие операции (выборка из базы, и т.п.).
ЧИМ пишет:
Вот это для меня вообще непонятно, это всё в классе?
Нет, создание экземпляра класса mysqli происходит в теле функции conn() при условии, что ранее этот объект не был создан.
ЧИМ пишет:
Первый раз просто сталкиваюсь с использованием extract
Эта функция, если говорить упрощённо, преобразует ассоциативный массив в переменные, при этом ключи массива становятся именами переменных, а значения массива - значениями переменных. И это всё импортируется в текущую область видимости.
ЧИМ пишет:
почему мы объявляем постоянный массив "static $conns = [];" и сразу проверяем существует ли в нём "$dbName"? Как до if(!isset($conns[$dbName])) в нём появится значение $dbName?
Поле $conns можно было бы объявить и не статичным, но тогда при каждом обращении к базе происходило бы создание объекта mysqli. Именно поэтому в условии написана проверка на его существование, ну а static будет хранить ранее сохранённые параметры.
 
 Top
ЧИМ
Отправлено: 18 Февраля, 2017 - 22:53:51
Post Id


Новичок


Покинул форум
Сообщений всего: 49
Дата рег-ции: Дек. 2016  


Помог: 0 раз(а)




Строитель пишет:
Нет, возвращается объект mysqli (если в процедурном - то это был бы тип "ресурс"), с которым вы будет производить дальнейшие операции (выборка из базы, и т.п.).

PHP:
скопировать код в буфер обмена
  1. function myDatabase() {
  2.     return conn('my_database');//[b]Просто возвращаем имя базы?[/b]
  3. }

На сколько я понял тут задаётся имя базы, но я его так же получаю из файла, так как "мастер создания подключения" его записывает в файл с настройками подключения и я его оттуда беру.

И вот эта строчка меня смущает "$conns[$dbName] = new mysqli($host, $user_name, $password, $dbName); " Почему например здесь не "$conns[$host]... " или вообще не отдельная переменная ? Ведь по идее мы можем после получения переменных из фала сразу сделать подключение с обычной переменной "$con = new mysqli($host, $user_name, $password, $dbName); " Просто так же объявим её статичной в начале "static $con;" и всё, зачем мы используем именно "$conns[$dbName]"? Или это делается просто для простоты проверки? Т.е. Если есть какое либо присвоенное значение в массиве $conns[] с элементом массива $dbName то просто вернуть это значение? Получается что в моём случае эта функция не совсем корректна. Дело в том что у меня сначала происходит просто подключение к серверу, а после этого создаётся база и используется в подключении во всех остальных манипуляциях. Но идея с "extract" отличная.
Скажите а если я сделаю следующим образом:
PHP:
скопировать код в буфер обмена
  1.  
  2.  
  3. function conSQL()
  4. {
  5. static $con;
  6.  
  7.  extract(require_once("config/connect.php"));
  8. if(isset($dbName))
  9. {
  10. $con = new mysqli($host, $user_name, $password, $dbName);
  11. }
  12. else
  13. {
  14. $con = new mysqli($host, $user_name, $password);
  15. }
  16. return $con;
  17. }
  18.  

т.е. по идее я смотрю в файл, если там присутствует переменная, то я пытаюсь подключиться с её значением, если же нет то я просто выполняю подключения к серверу MYSQL для последующего создания базы. Правильно?
 
 Top
Строитель Модератор
Отправлено: 19 Февраля, 2017 - 00:00:45
Post Id



Участник


Покинул форум
Сообщений всего: 1580
Дата рег-ции: Февр. 2014  
Откуда: Украина


Помог: 73 раз(а)




ЧИМ пишет:
На сколько я понял тут задаётся имя базы, но я его так же получаю из файла
Строго говоря, в функцию conn() передаётся имя файла, которое должно совпадать с именем базы данных, к которой вам необходимо произвести подключение.

Чтобы долго не ходить вокруг да около, то можно сказать так - этот код позволит вам использовать одновременное подключение к разным бд. Для этого вам нужно создать соответствующие пхп-файлы, по аналогии с приведённым примером (т.е., чтобы файл возвращал ассоциативный массив значений), и просто вызывать одну и ту же функцию, но передавая в неё разные параметры. См. пример:
Спойлер (Отобразить)


ЗЫ: Можно код упростить так, как предложили вы, но тогда потеряется возможность подключения к нескольким бд одновременно (если я всё верно понял)
 
 Top
armancho7777777 Супермодератор
Отправлено: 19 Февраля, 2017 - 10:06:03
Post Id



Активный участник


Покинул форум
Сообщений всего: 4526
Дата рег-ции: Февр. 2011  
Откуда: Москва


Помог: 221 раз(а)




Строитель пишет:
имя файла, которое должно совпадать с именем базы данных

Не обязательно. Переменную $dbName можно переопределить из конфига.
Т.е. "extract" затрёт раннее переданную переменную $dbName, если одноимённый ключ передать из конфига.

PHP:
скопировать код в буфер обмена
  1.  
  2. // File: /path/to/config/db/default.php
  3.  
  4. return [
  5.     'dbName'    => 'my_database',
  6.     'host'      => 'localhost',
  7.     'user_name' => 'dendy',
  8.     'password'  => '12345',
  9.     'charset'   => 'utf8',
  10. ];


PHP:
скопировать код в буфер обмена
  1. function conn($dbName = 'default') { /* .... */ }
  2. conn();
 
 Top
ЧИМ
Отправлено: 19 Февраля, 2017 - 14:47:49
Post Id


Новичок


Покинул форум
Сообщений всего: 49
Дата рег-ции: Дек. 2016  


Помог: 0 раз(а)




Там ошибка в примере(по крайней мере у меня этот пример в таком виде не работает).
Сейчас вот в таком виде работает
connect_1.php
PHP:
скопировать код в буфер обмена
  1.  
  2. <?PHP
  3. $con_arr = array (
  4.  'HOST'=>'localhost',
  5.  'DB'=>'base',
  6.  'LOGIN'=>'user',
  7.  'PASSW'=>'12345',
  8.  'charset'=>'utf8', );
  9.  

SqlDB.php
PHP:
скопировать код в буфер обмена
  1.  
  2. class SqlDB {
  3. function conn($DB)
  4. {
  5.     static $conns = [];
  6.  
  7.     if(!isset($conns[$DB])) {
  8.         require_once("apteka/config/connect_1.php");
  9.         extract($con_array);
  10.         $conns[$DB] = new mysqli($HOST,$LOGIN,$PASSW,$DB);
  11.         $conns[$DB]->set_charset($charset);
  12.     }
  13.  
  14.     return $conns[$DB];
  15. }
  16.  
  17. function myDatabase() {
  18.     return conn('my_database');
  19. }
  20. }
  21.  

(Отредактировано автором: 19 Февраля, 2017 - 15:08:47)

 
 Top
Строитель Модератор
Отправлено: 19 Февраля, 2017 - 14:56:09
Post Id



Участник


Покинул форум
Сообщений всего: 1580
Дата рег-ции: Февр. 2014  
Откуда: Украина


Помог: 73 раз(а)




ЧИМ пишет:
выдаёт ошибку: "Parse error: syntax error, unexpected '[' "
Проверьте версию пхп. Она должна быть не ниже 5.4. Если версия ниже, и нет возможности её поднять, тогда замените строку с сокращённым синтаксисом объявления массива на этот вариант:

static $conns = array();
 
 Top
Страниц (2): [1] 2 »
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Вопросы новичков »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB