Re: database access [message #174205 is a reply to message #174204] |
Thu, 26 May 2011 16:14 |
sheldonlg
Messages: 166 Registered: September 2010
Karma:
|
Senior Member |
|
|
On 5/26/2011 12:07 PM, sheldonlg wrote:
> On 5/26/2011 11:41 AM, Jerry Stuckle wrote:
>> On 5/26/2011 10:22 AM, sheldonlg wrote:
>>> On 5/26/2011 9:00 AM, Jerry Stuckle wrote:
>>>> On 5/26/2011 8:09 AM, sheldonlg wrote:
>>>> > On 5/25/2011 5:37 PM, Jerry Stuckle wrote:
>>>> >> On 5/25/2011 1:17 PM, Jivanmukta wrote:
>>>> >>> I new relatively new to PHP. I need your opinion if the following
>>>> >>> set
>>>> >>> of database functions make sense:
>>>> >>>
>>>> >>> function openDatabase() {
>>>> >>> global $db;
>>>> >>> try {
>>>> >>> $db = new PDO('mysql:host=' . MYSQL_SERVER . ';dbname=' .
>>>> >>> MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD);
>>>> >>> $db->exec('SET NAMES latin2');
>>>> >>> $db->exec('SET CHARACTER SET latin2 COLLATE latin2_general_ci');
>>>> >>> $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
>>>> >>> register_shutdown_function('closeDatabase');
>>>> >>> } catch (PDOException $e) {
>>>> >>> return false;
>>>> >>> }
>>>> >>> return true;
>>>> >>> }
>>>> >>>
>>>> >>> function closeDatabase() {
>>>> >>> global $db, $inTransaction;
>>>> >>> if ($inTransaction) {
>>>> >>> $db->rollBack();
>>>> >>> $inTransaction = false;
>>>> >>> }
>>>> >>> if (!is_null($db)) {
>>>> >>> $db = null;
>>>> >>> }
>>>> >>> }
>>>> >>>
>>>> >>> function queryDatabase($sql) {
>>>> >>> global $db, $inTransaction;
>>>> >>> $result = array();
>>>> >>> try {
>>>> >>> $qry = $db->query($sql);
>>>> >>> if (!empty($qry)) {
>>>> >>> $result = $qry->fetchAll();
>>>> >>> }
>>>> >>> } catch (PDOException $e) {
>>>> >>> if ($inTransaction) {
>>>> >>> $db->rollBack();
>>>> >>> }
>>>> >>> error(ERRMSG_DATABASE_OPERATION_FAILED);
>>>> >>> }
>>>> >>> return $result;
>>>> >>> }
>>>> >>>
>>>> >>> function execDatabase($sql) {
>>>> >>> global $db, $inTransaction;
>>>> >>> $result = array();
>>>> >>> try {
>>>> >>> $result = $db->exec($sql);
>>>> >>> } catch (PDOException $e) {
>>>> >>> if ($inTransaction) {
>>>> >>> $db->rollBack();
>>>> >>> }
>>>> >>> error(ERRMSG_DATABASE_OPERATION_FAILED);
>>>> >>> }
>>>> >>> return $result;
>>>> >>> }
>>>> >>>
>>>> >>> function startTransaction() {
>>>> >>> global $db, $inTransaction;
>>>> >>> $db->beginTransaction();
>>>> >>> $inTransaction = true;
>>>> >>> }
>>>> >>>
>>>> >>> function commitTransaction() {
>>>> >>> global $db, $inTransaction;
>>>> >>> $inTransaction = false;
>>>> >>> if ($db->commit()) {
>>>> >>> return;
>>>> >>> }
>>>> >>> $db->rollBack();
>>>> >>> error(ERRMSG_DATABASE_OPERATION_FAILED);
>>>> >>> }
>>>> >>>
>>>> >>> function rollbackTransaction() {
>>>> >>> global $db, $inTransaction;
>>>> >>> $inTransaction = false;
>>>> >>> if ($db->rollBack()) {
>>>> >>> return;
>>>> >>> }
>>>> >>> error(ERRMSG_DATABASE_OPERATION_FAILED);
>>>> >>> }
>>>> >>>
>>>> >>> function lockTables($tables) {
>>>> >>> return execDatabase('LOCK TABLES ' . join(' WRITE, ', $tables) . '
>>>> >>> WRITE');
>>>> >>> }
>>>> >>>
>>>> >>> function unlockTables() {
>>>> >>> return execDatabase('UNLOCK TABLES');
>>>> >>> }
>>>> >>
>>>> >> Kind of, and maybe a bit overkill. But personally I'd put it all in a
>>>> >> Database class. The code would be more flexible and less prone to
>>>> >> errors.
>>>> >>
>>>> >
>>>> > Further, I would not have globals. I would pass $db in via the
>>>> > constructor. Likewise, I would have $inTransaction be a class variable
>>>> > which gets set by the method startTransaction().
>>>> >
>>>>
>>>> That was part of the class, Sheldon. In fact, I wouldn't even pass $db
>>>> into the constructor; it (along with $inTransaction, as you note) would
>>>> be class variables. That way the rest of the program is completely
>>>> independent of the database (and you can have more than one database
>>>> active concurrently if you want).
>>>
>>> If you don't pass it in with the constructor, then you need something
>>> like a setDb($parameter) to set the class variable. Passing it along
>>> with the constructor does not limit you to only one database
>>> concurrently. After all, you could readily do
>>>
>>> $dbObj1 = new DatabaseClass($db1);
>>> $dbObj2 = new DatabaseClass($db2);
>>>
>>> What passing it along inside the constructor does is (a) it saves a line
>>> of code each time in the invocation process(es) and (b) uniquely
>>> identifies a particular instance of the class. Since the DatabaseClass
>>> _MUST_ have the db defined, there is no problem with passing it in with
>>> the constructor and no reason not to do so.
>>>
>>
>> A better way would be to pass the basic information to the constructor -
>> i.e. the host, userid, password and database name. Let the constructor
>> build the database object. That way it is completely encapsulated and
>> the rest of the program is not dependent on a database object. If he
>> later finds he wants to change database objects (i.e. maybe PDO is to
>> slow and he wants to use mysqli), he can do so without changing anything
>> in the rest of the program. The class is now more fully encapsulated.
>>
>> A very good reason for not passing it to the constructor.
>
> Good point. It would be best to pass those three instead. Point was that
> I was making is that it is best to pass what is _ALWAYS_ needed through
> the constructor. Your suggestion is better.
>
four, not three.
--
Shelly
|
|
|