Вопросы нуба в PDO, PHP и многом другом

LoneSimba

Нубило-всея-планеты
Второй вопрос: Вопросы нуба в PDO, PHP и многом другом

Пишу код своего недодвижка, решил сделать универсальность ДБ. Проверка Database.class.php выдает ошибку
Fatal error: Call to a member function query() on null in C:\xampp-\htdocs\RCE\functional\database.class.php on line 73

Собственно, вот код:
PHP:
require('../config.php');

class Database
{
    private $db;
     /**
      * Подключает ДБ через указанный драйвер
      * @param string $driver Драйвер ДБ. По умолчанию MySQLi
      */
     function load_DB($driver = 'mysqli')
    {
        global $config;

        switch ($driver) {
            case 'mysql':
                mysql_connect($config['db_host'],$config['db_user'],$config['db_pass'])
                                    or die("Connect error(".mysql_errno()."): ".mysql_error());
                mysql_select_db($config['db_name'])
                                    or die("DB connect error(".mysql_errno()."): ".mysql_error());
                mysql_set_charset('utf8')
                                    or die("Charset change error: ".mysql_error());
                break;

            case 'mysqli':
                $db = new mysqli("p:".$config['db_host'],$config['db_user'],$config['db_pass'],$config['db_name']);
                if($db->connect_error) {
                        die("Connect error(".$db->connect_errno."): ".$db->connect_error);
                }
                if(!$db->set_charset('utf8')) {
                        die("Charset change error: ".$db->error);
                }
                break;

            /*case 'pdo':
                $dsn = 'mysql:dbname='.$config['db_name'].';host='.$config['db_host'].';charset=UTF8';
                $user = $config['db_user'];
                $password = $config['db_pass'];

                try {
                    $pdo = new PDO($dsn, $user, $password);
                } catch (PDOException $e) {
                    echo 'Подключение не удалось: ' . $e->getMessage();
                }
                break;*/
              
            default:                    //Для того, чтобы не было никаких ошибок с неопределенным дравером
                $driver = 'mysqli';
                $this->load_DB($driver);
                break;
        }
    }

     /**
      * Для процедурного выполнения вызывается как обычная mysql_query($query), для выполнения каких либо операций над результатом запроса создается указатель $foo_query = query($driver,$query)
      * @param string $driver драйвер БД
      * @param string $query запрос в формате SQL
      */
    function query_DB($driver = 'mysqli', $query)
    {
        $db = $this->db;
        switch ($driver) {
            case 'mysql':
                mysql_query($query);
                break;

            case 'mysqli':
                $db->query($query);
                break;

            /*case 'pdo':
                $pdo->query($query);
                break;*/
              
            default:                    //Для того, чтобы не было никаких ошибок с неопределенным дравером
                $driver = 'mysqli';
                $this->query_DB($driver,$query);
                break;
        }
    }


     /**
      * Создается указателем $foo_nums = num_rows($driver,$query_result), где $query_result - ранее вызванная $foo_query, либо как обычная mysql_num_rows для процедурного выполнения
      * @param string $driver драйвер БД
      * @param string $query_result указатель ранее вызванной query_DB()
      */
    function num_rows_DB($driver = 'mysqli', $query_result)
    {
        switch ($driver) {
            case 'mysql':
                mysql_num_rows($query_result);
                break;

            case 'mysqli':
                $num_rows = $query_result->num_rows();
                break;

            /*case 'pdo':
                $num_rows = PDO::query("SELECT COUNT(*) AS ROW_COUNT FROM(".$query_result.")");
                break;*/

            default:
                $driver = 'mysqli';
                $this->num_rows_DB($driver, $query_result);
                break;
        }
    }
}

Про создание велосипеда мозги не мойте, прошу. И про default тоже. Ошибка указывается в query_DB, в $db->query();. По моей логике, эта переменная должна заполнится в load_DB, и в скрипте, откуда был вызван класс, идет первой load. Прямое указание MYSQLI не помогает.
 
Последнее редактирование:

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
И где работа по инициализации $this->db?
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
@LoneSimba, нет, глобальные переменные зло, не надо их использовать.

Я спросил, где ты в первом методе инициализируешь переменную, которую ты потом используешь во втором?
 

Фанат

oncle terrible
Команда форума
Про сам по себе факт изобретения велосипеда мыть не будем. Но вот конкретно этот велосипед ужасен, и не должен использоваться ни в коем случае.
 

LoneSimba

Нубило-всея-планеты
@LoneSimba, нет, глобальные переменные зло, не надо их использовать.

Я спросил, где ты в первом методе инициализируешь переменную, которую ты потом используешь во втором?
я уже понял. под глобальной я подразумевал ту, что в private. Сейчас инициализировал, ошибка ушла. И ведь всего одна строчка, а сколько решает.
 

LoneSimba

Нубило-всея-планеты
Про сам по себе факт изобретения велосипеда мыть не будем. Но вот конкретно этот велосипед ужасен, и не должен использоваться ни в коем случае.
А что делать? не ифами же делать.Или даже не свитч проблемы делает?
 

LoneSimba

Нубило-всея-планеты
Переделал 3 функцию, вот код
PHP:
function num_rows_DB($driver = 'mysqli', $query_result)
    {
        switch ($driver) {
            case 'mysql':
                $num_rows = mysql_num_rows($query_result);
                break;

            case 'mysqli':
                $num_rows = $query_result->num_rows;
                break;

            /*case 'pdo':
                $num_rows = PDO::query("SELECT COUNT(*) AS ROW_COUNT FROM(".$query_result.")");
                break;*/

            default:
                $driver = 'mysqli';
                $this->num_rows_DB($driver, $query_result);
                break;
        }

        return $num_rows;
    }
и, естественно, на num_rows ругается. Как к этому значению обратится отсюда? Или забить и делать код чисто на mysqli без попыток запила класса?
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
под глобальной я подразумевал ту, что в private.
WAT???

Сделай обертку над одним типом работы с БД. Сейчас с твоими передачами типа драйвера - это ноль универсальности. Тип драйвера должен выставляться в конфиге.
 

LoneSimba

Нубило-всея-планеты
WAT???

Сделай обертку над одним типом работы с БД. Сейчас с твоими передачами типа драйвера - это ноль универсальности. Тип драйвера должен выставляться в конфиге.
переделывать буду, в конфиге строчка есть такая. Просто думал вызывать из скрипта, свзанного с index.php. Ну если как вы предлагаете, то как реализовать? Как сделать это без свитчей\ифов я не представляю, "знаний" не хватает. Делаю то не для публикации, а чисто на случай, если на хостинге поддержки драйвера не будет. ПХП старая там, или, как вон с MYSQL, устареет. С PDO не знаком совсем, так, что с php.net удалось выцарапать написал, даже не тестировал. Сразу в коммент
 

AnrDaemon

Продвинутый новичок
Не знаком - познакомься… Проблем на один вечер…
 

LoneSimba

Нубило-всея-планеты
Переделал. С PDO попробую, но сейчас хочется с num_rows разобраться.
PHP:
class Database
{
     private $db;
     private $driver;

     function __construct(array $config)
     {
         if(!isset($config['driver'])) {
             $config['driver'] = 'mysqli';
             $this->driver = $config['driver'];
         } else {
             $this->driver = $config['driver'];
         }
     }

     /**
      * Подключает ДБ через указанный драйвер
      */
     function load_DB()
    {
        global $config;

        switch ($this->driver) {
            case 'mysql':
                mysql_connect($config['db_host'],$config['db_user'],$config['db_pass'])
                                    or die("Connect error(".mysql_errno()."): ".mysql_error());
                mysql_select_db($config['db_name'])
                                    or die("DB connect error(".mysql_errno()."): ".mysql_error());
                mysql_set_charset('utf8')
                                    or die("Charset change error: ".mysql_error());
                break;

            case 'mysqli':
                $db = new mysqli("p:".$config['db_host'],$config['db_user'],$config['db_pass'],$config['db_name']);
                if($db->connect_error) {
                        die("Connect error(".$db->connect_errno."): ".$db->connect_error);
                }
                if(!$db->set_charset('utf8')) {
                        die("Charset change error: ".$db->error);
                }
                break;

            /*case 'pdo':
                $dsn = 'mysql:dbname='.$config['db_name'].';host='.$config['db_host'].';charset=UTF8';
                $user = $config['db_user'];
                $password = $config['db_pass'];

                try {
                    $pdo = new PDO($dsn, $user, $password);
                } catch (PDOException $e) {
                    echo 'Подключение не удалось: ' . $e->getMessage();
                }
                break;*/
        }

        $this->db = $db;
    }

     /**
      * Для процедурного выполнения вызывается как обычная mysql_query($query), для выполнения каких либо операций над результатом запроса создается указатель $foo_query = query($driver,$query)
      * @param string $query запрос в формате SQL
      */
    function query_DB($query)
    {
        switch ($this->driver) {
            case 'mysql':
                mysql_query($query);
                break;

            case 'mysqli':
                $this->db->query($query);
                break;

            /*case 'pdo':
                $pdo->query($query);
                break;*/
        }
    }


     /**
      * Создается указателем $foo_nums = num_rows($driver,$query_result), где $query_result - ранее вызванная $foo_query, либо как обычная mysql_num_rows для процедурного выполнения
      * @param string $driver драйвер БД
      * @param string $query_result указатель ранее вызванной query_DB()
      */
    function num_rows_DB($query_result)
    {
        switch ($this->driver) {
            case 'mysql':
                $num_rows = mysql_num_rows($query_result);
                break;

            case 'mysqli':
                $num_rows = $query_result->num_rows;
                break;

            /*case 'pdo':
                $num_rows = PDO::query("SELECT COUNT(*) AS ROW_COUNT FROM(".$query_result.")");
                break;*/
        }

        return $num_rows;
    }
}
 

LoneSimba

Нубило-всея-планеты
И, уж до кучи, вопрос: делаю такой запрос в PDO, для подсчета значений в БД.
Код:
"SELECT COUNT(*) AS ROW_COUNT FROM("SELECT * FROM `users` WHERE `id`=1")"//подразумевается не прямой запрос в скобках, а указатель на выпосленный query запрос ранее
. Как его преобразовать для вывода, или лучше через columntCount? PS: columntCount выдает не верное значение. По запросу "SELECT * FROM `users` WHERE `id`=1" через num_rows 1(так оно и будет), а PDO пишет, что 14
 

Фанат

oncle terrible
Команда форума
Начнем с того, функция num_rows_DB в принципе не нужна.
нет ни одного случая, когда бы она пригодилась в работе.
нормальные базы данных вообще не имеют аналогичных функций

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

Кроме того, никакой "указатель" здесь все равно работать не будет
 

Фанат

oncle terrible
Команда форума
И, разумеется, самое главное что надо понимать при работе с ПДО - это что функция query() должна уметь работать с подготовленными выражениями.
 

LoneSimba

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

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

Кроме того, никакой "указатель" здесь все равно работать не будет
С указателем уже понял, ошибку выбивал. Ну, а если мне, допустим, надо будет подсчитать реальное число пользователей, у которых поле ban содержит false? MySQL его содержит, MySQLi тоже. А кроме них, да еще PDO я слышал только о SQLite
 

LoneSimba

Нубило-всея-планеты
И, разумеется, самое главное что надо понимать при работе с ПДО - это что функция query() должна уметь работать с подготовленными выражениями.
Код:
$pdo = new pdo('mysql:dbname='.$config['db_name'].';host='.$config['db_host'].';charset=UTF8',$config['db_user'],$config['db_pass']);
$query1 = $pdo->prepare("SELECT * FROM users WHERE id= ?");
$query1->bindParam(1,$in);
$in = 1;
$query1->execute();
echo $query1->columnCount();
вот так? так результат 14
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
@LoneSimba, columnCount? Зачем тебе это? Это количество столбцов, а не строк!
 

LoneSimba

Нубило-всея-планеты
@c0dex, точно. Просто сижу за монитором без перерывов часов так.... ежели с 11... 6 часов.
 
Сверху