Jump to content

Undefined variable and expects parameter 2 to be resource?


farban6

Recommended Posts

Hello there

 

I am trying to make a class variable called link so that it the function inside of select_DB can read that variable and get the connection details used to select the database inserted into the constructor. Problem is that it is throwing a PHP notice and a warning.

 

Notice: Undefined variable: link in C:\xampp\htdocs\xampp\fry\classes\connect_to_DB.php on line 59

 

Warning: mysql_select_db() expects parameter 2 to be resource, null given in C:\xampp\htdocs\xampp\fry\classes\connect_to_DB.php on line 59

 

this is the class that's causing all the fuss

 

<?php 

class connect_to_DB {

 var $database;
 var $link;


 function __construct($database)	{

	  $this->select_DB($this->database = $database);

 }

public function connect_DB($link)	{

	$link = mysql_connect(host, username, password);
	if (!$link) {
		die('Could not connect: ' . mysql_error());
	}
}

public function select_DB($database)	{

		$db_selected = mysql_select_db($database, $this->connect_DB($this->link = $link));

	if (!$db_selected) {
		die ('Can\'t use '.$database.' : ' . mysql_error());
	}

}
}
?>

 

Any help in the right direction will be greatly appreciated :)

Link to comment
Share on other sites

that fixed that particular problem but now it says

 

Could not connect:

 

 

config.php

 


<?php 
define("host", "localhost");
define("username", "root");
define("password", "");
?>

 

index.php

 

<?php 
include 'config.php';
$connect = new connect_to_DB("test");
?>

 

connect_to_DB.php

 


<?php 
class connect_to_DB {

 var $database;
 var $link;


 function __construct($database)	{

	  $this->select_DB($this->database = $database);

 }

public function connect_DB($link)	{

	$this->link = mysql_connect(host, username, password);
	if (!$link) {
		die('Could not connect: ' . mysql_error());
	}
}

public function select_DB($database)	{

		$db_selected = mysql_select_db($database, $this->connect_DB($this->link));

	if (!$db_selected) {
		die ('Can\'t use '.$database.' : ' . mysql_error());
	}

}
}

?>

 

Any suggestions?

Link to comment
Share on other sites

There are some conceptual issues going on with this code. Firstly, You don't seem to understand how parameter passing works, and return values from functions work.

 

For example here, where you error is originating from

$db_selected = mysql_select_db($database, $this->connect_DB($this->link = $link));

 

Lets examine this. Firstly, you use a variable $link. However, we are in the method: select_DB, where you have not defined $link yet. Yeah sure, its a parameter in the connect_DB method, but the scope of that variable is local to the connect_DB method. As such, you cannot access it in select_DB. When you use undefined variables, PHP gives them a value of undefined or null. So essentially what you are doing because of this part

($this->link = $link)

is setting your classes data member to a value of null.

 

Now, after this null assignment, we go into the connect_DB method. This method is below

public function connect_DB($link)	{

	$link = mysql_connect(host, username, password);
	if (!$link) {
		die('Could not connect: ' . mysql_error());
	}
}

 

Now remember how we assigned null to the argument earlier. Now the $link variable in this function is null. However, this doesn't really matter because we reassign it anyways. However, we are only reassigning the local $link variable, and our datamember, $this->link remains null. I'm assuming where you write host, username, password in the posted code, in the actual code is the actual username password and host (whether as hardcoded strings, or variables or whatever). I'm guessing this line works, as you didn't post anything about not being able to connect.

 

However, note that you don't return anything from this function. It just ends. However, what you don't consider is what happens when it ends. Remember, this function is called in the select_DB function so we return back. Recall this is here

$db_selected = mysql_select_db($database, $this->connect_DB($this->link = $link));

 

and you have the call to connect_DB as the second parameter to mysql_select_db. Recall that your function doesn't return anything, so what happens is this call essentially has the value of null. What you have, and the following are equivalent the way things are currently set up.

$db_selected = mysql_select_db($database, NULL));

 

This is why you are getting the second error.

 

Now, as far as the OOP goes, you seem to misunderstand the reason we have OOP. It isn't really about simply making classes, you have to set up your class correctly for it to be more useful than simply coding procedurally. Otherwise you basically have procedural code with the word class strewn about. Probably the most important and used concept of OOP is encapsulation. The concept is pretty simple. It basically means that your object is like a discrete entity in your code, with specific ways to input and output data to the rest of the program, but otherwise the data in the object is only available to your object, and data outside is only available outside. However, in your object, all your methods and datamembers are public. That means anyone using your class could set the variables to arbitrary meaningless values ("like setting your database member to the string 'hello') which could potentially break your object. This may seem like an example of something that would be obvious to you to not do, and so may never occur. But the ramifications of doing something similar in a more complex system are sometimes drastic, and may be difficult to spot.

 

What you should do with an object, is keep data that the user of the class doesn't need to mess with as private, but other things, like methods to invoke certain functionality in the class should be public. I will make some alterations in your class above that makes some use of encapsulation, and hopefully fixes the current problems.

 


class connect_to_DB {

//the user of this class has no need to change these two variables directly
//so why let them? We will use metators and accessors to interact with this data
private $databaseName;
private $link;


function __construct($database)	{
	//now before we even select a database, we need to connect to mysql first
	//now, our $link datamember will store our connection resource
	$this->link = mysql_connect(host, username, password);
	//it may be better to abstract that login data into its own class
	//bt thats a topic for later

	//instead of the old way, we set our member to the passed in argument
	$this->databaseName = $database;
	//remember, we just set that, and data members are available EVERYWHERE in the class
	//so there is no need to pass an argument as we already have it
	$this->select_DB();

}

//this is a function that is used to set up the class, and is called automatically by the constructor
//we don't need to let the user access this function directly
private function select_DB()	{
	//now we can just use our link datamember, as we defined it before. 
	$db_selected = mysql_select_db($this->databaseName, $this->link);

	if (!$db_selected) {
		die ('Can\'t use '.$this->databaseName.' : ' . mysql_error());
	}

}

//now, we need a way to change the database we are connected to!
//lets make a mutator to do so
public function change_DB($db_new){
	//we set our databaseName datamember to the new one.
	$this->databaseName = $db_new;
	//now that its set, we can just call select_DB again.
	$this->select_DB();
}

//Now what if we want to get the value for the $link or the $databaseName members
//the user may have some use with their values. lets make some accessors
public function get_DBName() {
	return $this->databaseName;
}
public function get_Connection() {
	return $this->link;
}

//and finally a simple query wrapper function to give it some extra functionality
public function query($sql){
	return mysql_query($sql);
	//we could add some fancy error handling and stuff
	//but thats a topic for later
}
}

//now how can I use this class? Well lets instantiate an object
$dbConn = new connect_to_DB('my_database');
//we are connected, we can do a query
$dbConn->query("SELECT something FROM somewhere WHERE some_column='some value'");

//maybe we should change the database
$dbConn->change_DB('different_database');
//do a different query on this new databse
$dbConn->query("SELECT something_else FROM somewhere_else WHERE some_other_column='some other value'");

Link to comment
Share on other sites

This has really opened my eyes and I tried to make this class with encapsulation in mind, I am going to have to read this lots further but the code you gave me works so I am marking this as solved. Thanks for the very helpful explanation and constructive critism, which will be my homework for this week :)

Link to comment
Share on other sites

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.