PHP, вопрос с переменной областью - PullRequest
0 голосов
/ 24 апреля 2011

У меня вопрос: я использую переменную $ db в моем общем коде скрипта и в одной из моих функций. Его цель - быть переменной, используемой для соединений MySQL. Мне нужно внутри функции, чтобы записать некоторые данные в базу данных. В моем сценарии я не могу предположить, что существующее соединение с БД будет открыто, поэтому я открываю новое и закрываю его до выхода из функции. После этого я получаю сообщение об ошибке после запуска скрипта, в котором говорится, что ссылка на MySQL неверна / не существует.

Единственное, что я могу прикрепить, - это в моем основном коде, я использую переменную $ db в качестве имени переменной для соединения с базой данных. Я также использую ту же переменную в функции. Я не думал, что это будет проблемой, потому что я не использую global перед $ db в функции. Это должно означать, что ссылка на $ db I в моей функции находится в закрытой области видимости функций, но, похоже, она закрывает общедоступное соединение с $ db.

Есть мысли?

Фрагменты моего кода:

database.php

db_connect()
{
 // open mysql db connection and return it;
}

db_close( &$db )
{
 // close the passed by reference db connection
}

api.php

api_verify( $keyid, $userid, $key )
{
  // open a new db connection
  $db = db_connect();

  // check for errors. if any errors are found note them in the db

  // close the db
  db_close($db);
}

main.php

include api.php;
include database.php;

// open a connection to the db
$db = db_connect();

// pull a list of things to process from the db and move through them one at a time
  // call api_verify() on each key before working through it's data.

db_close($db)

Ответы [ 3 ]

2 голосов
/ 24 апреля 2011

Для управления соединениями с БД вы можете создать класс, а не пару функций.Если там, где вы говорите «ссылка MySQL», точная ошибка относится к «ресурсу MySQL», то вы используете устаревшее расширение mysql и должны переключиться на более современное расширение, такое как PDO.

class DBConnection {
    protected static $_connections = array(),
    static connect($dsn) {
        if (!isset(self::$_connections[$dsn])) {
            $credentials = self::getCredentials();
            /* Create connection. For example: */
            try {
                self::$_connections[$dsn][0] = new PDO($dsn, $credentials['username'], $credentials['password']);
            } catch (PDOException $exc) {
                // erase the frame w/ password from call trace to prevent leak.
                throw new PDOException($exc->getMessage(), $exc->getCode());
            }
            /* End create connection example */
            self::$_connections[$dsn][0]->dsn = $dsn;
        }
        ++self::$_connections[$dsn]['count'];
        return self::$_connections[$dsn][0];
    }
    static close($db) {
        if (isset(self::$_connections[$db->dsn])) {
            if (--(self::$_connections[$db->dsn]['count']) < 1) {
                unset(self::$_connections[$db->dsn]);
            }
        }
    }
    static getCredentials() {
        /* credentials can be stored in configuration file or script, in this method, or some other approach of your own devising */
    }
}

Обратите внимание, что это не совсем ООП (это так, но только в техническом смысле).Вышесказанное не подходит для модульного тестирования.Если вы хотите более OO-подход (который будет более подходящим для модульного тестирования), расширьте или оберните PDO.Использование внедрения зависимостей также может помочь с проблемами сцепления , описанными выше.

1 голос
/ 24 апреля 2011

Я предполагаю, что вы открываете соединение с одной и той же базой данных с одним и тем же именем пользователя / паролем в каждом из мест, где вы вызываете db_connect.При этом, если ваш db_connect явно не указывает, что вы создаете новую ссылку, он вернет уже открытую ссылку. Если эта ссылка затем закрывается с помощью db_close (), она также закроет другое соединение, так как ссылка являетсятак же.Если вы используете mysql_connect для подключения к базе данных, он принимает аргумент под названием новая ссылка

new_link Если второй вызов mysql_connect () выполняется с теми же аргументами, новая ссылка не будет установлена, но вместо этого,идентификатор ссылки уже открытой ссылки будет возвращен.Параметр new_link изменяет это поведение и делает mysql_connect () всегда открывающим новую ссылку, даже если mysql_connect () был вызван ранее с теми же параметрами.В безопасном режиме SQL этот параметр игнорируется.

См. http://php.net/manual/en/function.mysql-connect.php

Я не уверен, что это проблема, с которой вы столкнулись.Надеюсь, это поможет.

1 голос
/ 24 апреля 2011

Я бы предположил, что происходит, если соединение отменяется, потому что соединение уже существует, а затем закрытие завершает текущее соединение.
Я бы порекомендовал либо А) установить соединение в начале файла, ипросто знайте, что это всегда там (что я делаю);или B) проверьте, установлена ​​ли переменная $ db, если нет, то создайте соединение и всегда завершайте соединение в конце файла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...