So I have a DB set up and I'm using a class to connect to it that extends Mysqli. Here are the relevant lines of code:
class Db extends Mysqli {
public $result = Array();
function __construct() {
parent::__construct(DB_HOST, DB_USER, DB_PASS, DB_DB);
}
I've checked the connection info, and it works fine with the mysql_connect() function.
My PHP version is 5.3, and I'm using MAMP 1.9.5 to run the environment.
So on to the issue I'm having - if I var_dump() the connection, it returns as NULL. Not false, but null. Now I've checked the specs and, just like it's predecessor mysql_connect(), it is supposed to return false in case of the connection failing. So what possible circumstance would return false?
You are not showing the complete code. This is what you have done:
class Db extends Mysqli {
function __construct() {
$r = parent::__construct(DB_HOST, DB_USER, DB_PASS, DB_DB);
var_dump($r);
}
}
And naturally this returns NULL. The parent constructor never returns anything. Constructers are not supposed to return anything. They fill up the freshly created object instance.
You will find the connection handle and other properties in the returned object, after your constructor is done.
I'm guessing it's because of your capitalization. Extending the nonexistent class Mysqli works, and its nonexistent method connect() seems to return NULL
class Db extends Mysqli
Should be
class Db extends mysqli
#Michael is likely right about the spelling issue, but there's another issue here:
Why are you not using PDO? PDO is installed by default on PHP 5.1 and newer.
PDO abstracts the database layer so you can write code against any database that supports PDO without having to make majorchanges.
Related
I try to test a method that makes a SELECT query and return the rows found. I would like to check that this method doesn't return something else, given a dataset. I found so many docs about creating the dataset but nothing about using it in my case... Thanks for your help.
The method to test is:
class A
{
public static function myMethod()
{
$result = mysql_query("SELECT * FROM user");
[...]
return $rows;
}
}
The test class is:
class ATest extends PHPUnit_Extensions_Database_TestCase
{
protected $pdo;
public function __construct()
{
$this->pdo = new PDO('mysql:host=localhost;dbname=db_name',
'login', 'password');
}
public function getConnection()
{
return $this->createDefaultDBConnection($this->pdo, 'db_name');
}
public function getDataSet()
{
return $this->createFlatXMLDataSet('mydataset.xml');
}
public function testMyMethod()
{
$actual = A::myMethod();
$this->assertEquals(array([...]), $actual);
// For this test, I get a mySQL error "No database selected"
// in A::myMethod()!
}
}
Here is the content of mydataset.xml:
<?xml version="1.0" ?>
<dataset>
<user iduser="1" name="John" />
<user iduser="2" name="James" />
</dataset>
what I did in my case was I made the connection to the database using pdo like so:
static private $pdo=null;
private $conn=null;
public function getConnection()
{
if($this->conn===null)
{
if(self::$pdo===null)
{
self::$pdo = new PDO("mysql:host=yourhost;dbname=yourdbname_",
"yourusername", "yourpassword");
}
$this->conn= $this->createDefaultDBConnection(self::$pdo, 'yourdbname_');
return $this->conn;
}
},
then as for the test, this block below gets all the values in the testdb and compares it with the xml file.
public function testGetAll()
{
$resultingTable = $this->db
->createQueryTable("yourtable",
"SELECT * FROM yourtable");
$expectedTable = $this->getDataSet()
->getTable("yourtable");
$this->assertTablesEqual($expectedTable,
$resultingTable);
}
That worked fine for me and should allow you get all the values from the testdb and assert that they are the same with the xml values.
Just like in your real application, you need to connect to the database before you can call it. The mysql_query() function relies on a previous call having been made to mysql_connect(). If you're only calling the one class method in isolation, then you won't have called the connect function, so you won't have a connection, and so your query command won't know what database it needs to query.
The PDO connection being used in the test class is explicitly separate from and not used by the methods being tested (this applies even if those methods also use PDO); you need to create a connection for the query.
The solution here is to include a call to your DB connection method at the start of the test. This could be in the unit test method, or in the setUp() method of the test class, or in a bootstrap file that PHPUnit calls before running any of the tests. Which of these you use will depend on how many DB tests you need to run and across how many test classes.
Straying slightly off topic, but still relevant: I note that your code is using the old mysql_xxx() functions (ie mysql_query()). It would be advisable to avoid using these functions, as they are obsolete and insecure, and in the process of being deprecated by the PHP dev team. You will therefore find yourself unable to upgrade your PHP version in the future if you keep using them.
Use mysqli_xxx() instead (or PDO, as per your test class).
Back on topic, and in fact doing this will also lead you toward fixing the problem you're having anyway, since both mysqli and PDO require the connection object to be available when calling their functions/methods, so you'll have to have a valid connection object in order to even have valid syntax to call the query. Switching to mysqli or PDO will therefore force you to write your code in a way that solves the problem in the question.
This question differs from checking if the specific connection is alive or not which I found in SO itself and in Google Search Resutls.
What I want is to check if the mysql connection has already been established. I need to check this, because I have many modules which needs connection to function. The same module is sometimes called where there is no connection and sometimes called when there is already an connection.
You should simply call mysql_connect with the same arguments. If an identical connection already exists, it will simply be reused.
That was the lazy answer. Obviously the better way would be to structure your program in a way that you know what your program's status is. Getting rid of the age-old, deprecated mysql_ extension is a first step. Use mysqli or PDO, both of which do not support implicit connections but require you to hand a variable around that represents your connection. That's what you should do anyway for a sane and modular application structure, then you would not have these kinds of questions.
I suggest use singleton pattern and some OO.
class Singleton{
private static $instance=null;
public function connection(){
if(self::$instance==null){
self::$instance = mysql_connect();
}
return self::$connection;
}
}
class TableA extends Singleton{
function find($id){
$query="select * from `A` where `id`='$id'";
mysql_query($query, $this->connection());
... // other codes
}
}
hope that will help you
I'm getting this strange behavior:
Imagine you have a class that simply creates a connection to MySQL and returns the connection link.
class Connection {
private $conn;
public function __construct() {
$this->conn = mysql_connect(.....);
}
public function getConn() {
return $this->conn;
}
}
Now, if I try to use the connection link (of course instantiating Connection and using $instance->getConn()), I can use the link in the mysql_query function, but I cannot use it in mysql_error and mysql_errno (they always return respectively '' and 0, even if the query executed is absolutely wrong).
But!! If I place the link creation in the same class of the mysql_query, mysql_errno and mysql_error, all works perfectly!!
Has anyone had the same problem?
mysql
is deprecated, consider using
mysqli
http://www.php.net/manual/en/mysqli.query.php
I am making my first steps in the OOP world - please bear with me.
I know that having many ongoing mySQL connections open at the same time can be fatal for performance, so it should be a good idea to make a database class that takes this into account.
Is $this->session->write(...); going to result in a new mySQL connection being opened each time?
Or is that up to the "persistent connection" feature in mySQL?
Here's the code:
abstract class database {
function __construct() {
//mysql_connect()
}
}
class session extends database {
function write () {
// mysql_query(--.)
}
}
Is session handler some kind of specialized type of database? It is not, so don't use inheritance (a is a relationship). Session handler uses database so you should use composition (a has a relationship):
class Session {
protected $db;
public function __construct(DB $db) {
$this->db = $db;
}
public function write() {
$this->db->query(...);
}
}
$db = new DB(...);
$session = new Session($db);
Also, don't use mysql_*() functions. Use much more powerful PDO.
Returning to your question... mysql_connect() will be executed every time you create a new Database object. However in this case Session is an object of type Database so every time you write new Database() or new Session() the constructor is invoked, therefore mysql_connect() is invoked as well.
PS. mysql_connect() function won't create a new connection if specified connection already exists. Check 4th argument of this function to learn more.
mysql_query will create a new connection only if no previous mysql connection has been made. Otherwise, it will either use the connection you specify or the last connection opened with mysql_connect. http://php.net/manual/en/function.mysql-query.php
Why not
class database {
function __construct() {
//mysql_connect()
}
function write() {
//query the DB
}
}
I'm not sure of the syntax, I don't do OOP PHP. Anyway, in your structure above a new connection would be opened for each "session" instance so assuming you only create one instance of "session" you won't be openeing loads of database connections.
Can anyone help me with this?
I have this function in a singleton class. The error it is giving me back is that it cannot find the class.
First I thought it had something to do with the autoloader, but I did spl_autoload_unregister('libloader') and it still gives the same error?
The host is running php 5.
public static function getInstantie()
{
if (!self::$instantie)
{
$config = config::getInstantie();
$db_type = $config->config_waarden['database']['db_type'];
$hostnaam = $config->config_waarden['database']['db_hostnaam'];
$dbnaam = $config->config_waarden['database']['db_naam'];
$db_wachtwoord = $config->config_waarden['database']['db_wachtwoord'];
$db_gebruikersnaam = $config->config_waarden['database']['db_gebruikersnaam'];
$db_poort = $config->config_waarden['database']['db_poort'];
self::$instantie = new PDO("$db_type:host=$hostnaam;port=$db_poort;dbname=$dbnaam",$db_gebruikersnaam, $db_wachtwoord);
self::$instantie-> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
return self::$instantie;
}
thanks, Richard
PDO is enabled by default with a set of database drivers:
http://au.php.net/manual/en/pdo.installation.php
But the build of PHP you are working with could have it disabled. Autoloading will have no effect on whether or not the PDO class will be found.
Create a PHP info file and check to see if the PDO section exists. If it doesn't, then your issue is most likely because it wasn't built into your php installation.
is that function inside of a class that extends PDO? If not, can you try to make that function inside of a class that extends PDO and instead of self call the functions using keyword parent?