Jump to content

Recommended Posts

Well I am encountering this dilemma at the moment. The project I am working on has database instantiated with PDO like this:

 

$dsn = "mysql:host={$dbhost};dbname={$dbname}";
$db = new PDO($dsn, $dbuser, $dbpass);

 

But there is a problem with variable scope in functions. Whenever I call a function, the database object $db is not carried over unless it is defined as global variable or in superglobal array like this: (replacing $GLOBALS['db'] with $db will give an error, saying its not an object)

 

$GLOBALS['db'] = $db;
function myfunc($query){
  $stmt = $GLOBALS['db']->prepare($query);
  $stmt->execute();
}

 

And then I get the problem of global variables. They are not secure and require lots of memories to store, definitely not a good practice for a project that is ever expanding. However, I cannot think of an easier way of rewriting the code without making it more complex and messy to read. Sure I can instantiate the database object in every function call, but this means the object is redefined again and again if I call multiple functions at the same time.

 

Perhaps I can resolve this problem by completely rewriting the codes to be fully Object oriented, but that will take weeks or even months. Can anyone of you think of a better way of passing database object variable to each individual function? Please help.

Link to comment
https://forums.phpfreaks.com/topic/259250-about-php-globals-and-database/
Share on other sites

So you are saying that registering globals for database information actually is a good practice? I thought using global variables is always bad unless you work on an extremely small project.

 

And if not, I have to pass the database info in all my functions like this?

 

function func1($db, $query){
    $stmt = $db->prepare($query);
    $stmt->execute();
}

function func2($db, $query2){
    $stmt = $db->exec($query2);
}

function func3($db, $query3){
    $stmt = $db->prepare($query3);
    $stmt->execute();
    $obj = $stmt->fetchObject();
    return $obj;
}

 

And there is no other way to improve the script?

No, thorpe is saying to never use globals at all, and to pass your db into the functions via their argument lists, like you did in the code above.

 

The same general approach would be used in OOP as well.

 

I see, so the problem still occurs even after the conversion into fully object-oriented codes is complete? Oh man what a pain, but I get what you are saying now.

I wouldn't consider that a problem.  Scope is a necessary part of programming, especially OOP, where objects are supposed to have hard boundaries.  But, even in a procedural environment, scope and encapsulation allow you to create modular code through functions.

 

The thing to remember is that if your code has an external dependency, like a function that has to use a db connection, you need to pass that dependency to the code that uses it in an explicit way.  The way PHP (and other languages) do it is via the argument list.

 

In OOP it's actually a bit easier, as you only need to inject the dependency in once, either right when you need it, or when the object is created.  You can store the dependency as an object member, and use it whenever you want.  And, since objects are always passed by reference, the dependency object can be passed to others with little overhead.

I wouldn't consider that a problem.  Scope is a necessary part of programming, especially OOP, where objects are supposed to have hard boundaries.  But, even in a procedural environment, scope and encapsulation allow you to create modular code through functions.

 

The thing to remember is that if your code has an external dependency, like a function that has to use a db connection, you need to pass that dependency to the code that uses it in an explicit way.  The way PHP (and other languages) do it is via the argument list.

 

In OOP it's actually a bit easier, as you only need to inject the dependency in once, either right when you need it, or when the object is created.  You can store the dependency as an object member, and use it whenever you want.  And, since objects are always passed by reference, the dependency object can be passed to others with little overhead.

 

umm dependency injection? Mind explaining a bit about that? Thx.

Symfony has a good description in there docs too.

 

http://symfony.com/doc/current/components/dependency_injection.html

 

Damn it man, I'm trying to point as many people toward my framework as I possibly can without looking like I'm spamming the place :)

 

Ah, shit.  :P

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.