Member Avatar for LastMitch

Hi,

I been learning OOP slowly. I'm stuck how to resolved an function query() on a non object issue.

My files are very basic:

This is my db.php file:

<?php
global $db;

class foo_mysqli extends mysqli {
    public function __construct($host, $user, $pass, $db) {
        parent::__construct($host, $user, $pass, $db);

        if (mysqli_connect_error()) {
            die('Connect Error (' . mysqli_connect_errno() . ') '
                    . mysqli_connect_error());
        }
    }
}

$db = new foo_mysqli('localhost', 'my_user', 'my_password', 'my_db');

$db->close();
?>

This is my function.php file

<?php
include("db.php");

function PM() {
        $sql = "SELECT * FROM posts";
        $result = $db->query($sql) or die("It's not connecting");
        while($row = $result->fetch_assoc($sql)) {
        echo $row['Content'];
    }
}
?>

This is my index.php file (This is where my data is echo out):

<?php
include('include/function.php');
PM();
?>

The error I'm having is in the function.php on line 6.

Which is this line:

$result = $db->query($sql) or die("It's not connecting");

I try to used this format and it didn't work well either it kept saying (mysqli_query() expects parameter 1 to be mysqli):

<?php
include("db.php");

function PM() {
        $query = "SELECT * FROM posts";
        $result = mysqli_query($mysqli, $query) or die(mysqli_error($mysqli));
        while($row = mysqli_fetch_assoc($query)) {
        echo $row['Content'];
    }
}
?>

and this

<?php
include("db.php");

function PM() {
        $sql = $db->query("SELECT * FROM posts") or die("Problem with query");
        while($row = mysqli_fetch_assoc($sql)) {
        echo $row['Content'];
    }
}
?>

Any Suggestions and explanation will help. I appreciate it. Thanks!

Hi LastMitch,

Think it is bad practice to have the DB call in the class file.

From db.php remove 15 & 16.

Call this from with in function.php

<?php
include("db.php");
function PM() {

        $db = new foo_mysqli('xx','xxx','xxxx','xxxxx');

        $sql = "SELECT * FROM posts";
        $result = $db->query($sql) or die("It's not connecting");
        while($row = $result->fetch_assoc($sql)) {
        echo $row['Content'];

        $db->close();

    }
}
?>

Not sure if that helps. Half asleep now :)

edit: http://devzone.zend.com/255/using-ext-mysqli-part-ii_extending-mysqli/

oh and remove global $db;

The function does not know about the mysqli object. You should either pass it as a parameter or initialize mysqli within the function (as lastMitch suggested).

$mysqli = new $mysqli('host', 'user', 'password', 'db');

function PM($mysqli) {
    $query = "SELECT * FROM posts";
    $result = mysqli_query($mysqli, $query) or die(mysqli_error($mysqli));
    while($row = mysqli_fetch_assoc($query)) {
        echo $row['Content'];
    }
}

or

$db = new $mysqli('host', 'user', 'password', 'db');

function PM($db) {
    $sql = $db->query("SELECT * FROM posts") or die("Problem with query");
    while($row = mysqli_fetch_assoc($sql)) {
        echo $row['Content'];
    }
}
Member Avatar for LastMitch

@Squidge

Thanks for the reply & explanation & link. I will look into it.

Member Avatar for LastMitch

@broj1

Thanks for the reply & explantion. I will test it out.

Member Avatar for LastMitch

@Squidge

I'm still getting that error. I will look at your link.

@broj1

I'm getting this error:

Missing argument 1 for PM()

This is the changes I made from my db:

This the db.php file:

  //connect to server and select database
  $mysqli = mysqli_connect('host', 'user', 'password', 'db');

  //if the connection fails, stop script execution
  if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
  }

This is my function.php file:

<?php
include("db.php");

$mysqli = new $mysqli('host', 'user', 'password', 'db');

function getPosts($mysqli) {
        $sql = $mysqli->query("SELECT * FROM posts") or die("Problem with query");
        while($row = mysqli_fetch_assoc($sql)) {
        echo $row['Content'];
    }
}
?>

Any suggestions?

When you call the function you have to pass it a parameter.

// this is a function declaration only
function getPosts($mysqli) {
    $sql = $mysqli->query("SELECT * FROM posts") or die("Problem with query");
    while($row = mysqli_fetch_assoc($sql)) {
        echo $row['Content'];
    }
}

// now, to use the function first initialize the mysqli object
$myDbObj = new $mysqli('host', 'user', 'password', 'db');

// then call the function with the object as a parameter
getPosts($myDbObj);
Member Avatar for LastMitch

@broj1

When you call the function you have to pass it a parameter.

Thanks for the reply and comment. I will work on it and test it out.

Member Avatar for LastMitch

@broj1

I make some adjustments:

I change my DB connection from this:

<?php
global $db;
class foo_mysqli extends mysqli {
public function __construct($host, $user, $pass, $db) {
parent::__construct($host, $user, $pass, $db);
if (mysqli_connect_error()) {
die('Connect Error (' . mysqli_connect_errno() . ') '
. mysqli_connect_error());
}
}
}
$db = new foo_mysqli('localhost', 'my_user', 'my_password', 'my_db');
$db->close();
?>

To this:

<?php
function myDbObj(){
global $mysqli;

//connect to server and select database
$mysqli = mysqli_connect('host', 'user', 'password', 'db');

//if the connection fails, stop script execution
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
  }
}
?>

I'm not sure if the OOP connection is intefering with the function code so I change it back to simple connection.

This is the function.php code:

<?php
include("db.php");
myDbObj();

function getPosts($mysqli) {
$sql = $mysqli->query("SELECT * FROM posts") or die("Problem with query");
while($row = mysqli_fetch_assoc($sql)) {
echo $row['Content'];
    }
}
// now, to use the function first initialize the mysqli object
$myDbObj = mysqli_connect('host', 'user', 'password', 'db');
// then call the function with the object as a parameter
getPosts($myDbObj);
?>

I only have 2 functions that echo content. 1 is PM() function and the other getPost() function.

I'm still getting the same error:

function query() on a non object issue.

There's something I'm doing wrong that keep this happening. I just don't know where. I test and try the the code you provided and I'm still getting the same error this line:

$sql = $mysqli->query("SELECT * FROM posts") or die("Problem with query");

I mean I try this:

function getPosts($mysqli) {
$query = "SELECT * FROM posts";
$result = mysqli_query($mysqli, $query) or die(mysqli_error($mysqli));
while($row = mysqli_fetch_assoc($result)) {
echo $row['Content'];
        }
}

and this

function getPosts($mysqli) {
$sql = $mysqli->query("SELECT * FROM posts") or die("Problem with query");
while($row = mysqli_fetch_assoc($sql)) {
echo $row['Content'];
        }
}

it didn't work either. Does it have to do with function()?

You changed the mysql connection function from OOP mode to procedural mode. The OOP mode initialized a mysqli object which has methods you can call. But the procedural mode does not initialize the object so you can not call it's methods (i.e the query method). Why did you do that?. The OOP mode is preferred (from my point of view).

// for this to use you need a mysqli object
$sql = $mysqli->query("SELECT * FROM posts") or die("Problem with query");

If you do not have a mysqli object (i.e. you do it procedural style), your connection function has to return the link.

function myDbObj(){

    // this does not have to be global
    global $mysqli;

    //connect to server and select database
    $link = mysqli_connect('host', 'user', 'password', 'db');

    //if the connection fails, stop script execution
    if (mysqli_connect_errno()) {
        printf("Connect failed: %s\n", mysqli_connect_error());
        exit();

    // otherwise return the link
    } else {
        return $link;
    }
}

Then you shoot the query:

$result = mysqli_query($link, "SELECT * FROM posts")

Haven't tested the code, see it here: http://www.php.net/manual/en/mysqli.query.php.

Member Avatar for LastMitch

@broj1

Why did you do that?

No, I can switch it back. It's just that I'm curious why the function() is not working. The db is connected with the OOP code and the mysqli code works fine.

The OOP mode is preferred (from my point of view).

Thanks. I just want to know the best way of connecting beside PDO. So OOP with MYSQLI is good.

I will try this code:

$result = mysqli_query($link, "SELECT * FROM posts")

I don't think I seem that one before. I think it might work.

I just want to know the best way of connecting beside PDO. So OOP with MYSQLI is good.

In most cases PDO is the best way to do it, but you need at least PHP 5 for it, it won't work in older versions. The good side is that it somehow makes you independent of database vendor since it supports quite a many of them, so you can change a database and still use the same code. But it won't support all missing or proprietary functionanities of different databases. There are abstraction layers that do that better (I used PEAR MDB2).

If you plan to use only MySql then mysqli exstension is equaly good.

The OOP mode is preferred (from my point of view).

Both OOP and procedural modes do their job OK. I prefer OOP way just because most (if not all) frameworks and abstraction layers are OOP and is just good if you are familiar with this approach and use it consistently.

$result = mysqli_query($link, "SELECT * FROM posts")

This is mysqli used in procedural way. There is also a OOP version of this function:

$mysqli->query("SELECT * FROM posts");

See examples of both approaches here.

Member Avatar for diafol

From what I saw earlier (I didn't really follow the code as they were mostly snippets), you have a

$db->close

After instatiating the $db object, so it's doubtful that you can then run a query on it.

I'd approach this by making a db crud class, that you then call.

$db = new foo_mysqli(...);
$postResource = $db->selectRes('posts');

SO in your foo_mysqli class you could have something like:

public function selectRes($table, $fields=NULL){
    $f = ($fields) ? '`'.implode('`,`', $fields).'`' : '*';
    return $dbh->query("SELECT $f FROM `$table`");
}

I've not included any error handling etc. You could extend the method (or create other method) to return an associative multidimensional array etc.

Member Avatar for LastMitch

@broj1

I can't seem to fixed this error:

function query() on a non object issue.

So I try this one:

$mysqli->query("SELECT * FROM posts");

It didn't work either so I try this:

function getPosts() {
$mysqli = new mysqlimysqli_connect('host', 'user', 'password', 'db');
$q = "SELECT * FROM posts";
$q = $mysqli->query($mysqli->fetch_assoc($q)) or die("Problem with query");
while($row = mysqli_fetch_assoc($q)) {
echo $row['Content'];
}
}

Then an new error pop up Call to undefined method mysqli::fetch_assoc()

I think I forgot to mention this is the first time I'm doing OOP connection to database. The preivous thread I posted was just OOP examples.

So I decide to move away from this issue with function query() on a non object issue.

So I'm using OOP style now:

This is my db.php file which is the same:

<?php
global $db;
class foo_mysqli extends mysqli {
public function __construct($host, $user, $pass, $db) {
parent::__construct($host, $user, $pass, $db);
if (mysqli_connect_error()) {
die('Connect Error (' . mysqli_connect_errno() . ') '
. mysqli_connect_error());
}
}
}
$db = new foo_mysqli('localhost', 'my_user', 'my_password', 'my_db');
$db->close();
?>

This is my new function.php file:

<?php
include("db.php");

$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db');

if ($mysqli->connect_error){
    echo "There was a connection error: ". $mysqli->connecterror;}

class Posts {

private $db;

function __construct($mysqli) {

    $this->db = $mysqli;

}

public function getPosts(){

$query = "SELECT * FROM posts";

$sql = $this->db->query($query);

$result = $sql->fetch_assoc();

return $result;

}

}

$Posts = new Posts($mysqli);
?>

This is my index.php file now:

<?php
include('include/functions.php');

echo $Posts->getPosts();
?>

By what I did there's no error appearing which I'm very happy. But I have another since I change to OOP style. How do I get data which is the OOP style?

This is my original code:

Front page which is the example I was having issue with but now solved:

function getPosts($mysqli) {
$query = "SELECT * FROM posts";
$result = mysqli_query($mysqli, $query) or die(mysqli_error($mysqli));
while($row = mysqli_fetch_assoc($query)) {
echo $row['Content'];
}
}

Back page:

function getPosts() {
    $query = mysqli_query("SELECT * FROM posts") or die(mysqli_error($mysqli));
    if(mysqli_num_rows($query) == 0) {
        echo "No Posts Were Found";
    } else {
        while($row = mysqli_fetch_assoc($query)) {
        echo $row['Content'];
    }

The Back page is how I get the data in my database.

How do I used mysqli_num_rows() & mysqli_fetch_assoc() in OOP style which is in this:

$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db');

if ($mysqli->connect_error){
    echo "There was a connection error: ". $mysqli->connecterror;}

class Posts {

private $db;

function __construct($mysqli) {

    $this->db = $mysqli;

}

public function getPosts(){

$query = "SELECT * FROM posts";

$sql = $this->db->query($query);

$result = $sql->fetch_assoc();

$row = $result->num_rows;

return $result;

}

}

$Posts = new Posts($mysqli);

echo $Posts->getPosts();

I add this:

$row = $result->num_rows;

It didn't fetch the $row['Content'];.

Maybe I didn't understand how it works correctly.

Any suggestions? I apprecaite your patience trying to help me learn.

Do have any links or examples that show how mysqli_num_rows() & mysqli_fetch_assoc() works in OOP style.

This is the first time I'm using OOP relative with the database.

Member Avatar for LastMitch

@diafol

Thanks for the reply and explanation.

The example you posted was a bit too advance for me to understand. So I took note of that example maybe in the future I can learn it.

Thanks

There are many questions here, I hope I manage to follow the main track :-). I will do it in couple of posts so we stay organized (in other words: you can not swallow a whole watermellon, you have to cut it in pieces).

I think foo_mysqli class is unnecessary here for two reasons: 1. you are not really adding anything to the mysqli class (which is a purpose of extending an existing class) but that would be okay; 2. you are not using it anywhere, you are using mysqli class in other scripts.

I am not saying that you should not do it this way. You can extend mysqli but then try to add some useful functionality to it like various ways of handling errors (display the errors during development, log the errors in production, provide default connection parameters etc). The following is the class I use for connecting and you can use it as an example (see the comments in it):

/**
 * This class establishes a connection to Mysql database using mysqli extension
 */
class dbConnMySqli
{
    // connection parameters
    protected $host = '';
    protected $user = '';
    protected $pass = '';
    protected $db = '';

    // mysqli object
    protected $mysqliObj = null;

    /**
     * Initialize connection parameters if set
     * 
     * @param string host
     * @param string $db_user
     * @param string $db_pass
     * @param string $db_name
     */
    public function __construct(
        $db_host = null, 
        $db_user = null, 
        $db_pass = null, 
        $db_name = null
    )
    {
        if($db_host && $db_user && $db_pass && $db_name) {

            $this->setConnParams($db_host && $db_user && $db_pass && $db_name);
        }
    }

    /**
     * Set connection parameters for a new connection
     *
     * @param string $db_host
     * @param string $db_user
     * @param string $db_pass
     * @param string $db_name
     */
    public function setConnParams(
            $db_host,
            $db_user,
            $db_pass,
            $db_name
    )
    {
        $this->host = $db_host;
        $this->user = $db_user;
        $this->pass = $db_pass;
        $this->name = $db_name;
    }

    /**
     * Set default connection parameters for a new connection
     *
     * @param string DB host
     * @param string DB user
     * @param string DB password
     * @param string DB name
     */
    public function setDefaultConnParams()
    {
        $this->host = 'localhost';
        $this->user = 'test';
        $this->pass = '';
        $this->name = 'test';
    }

    /**
     * Returns mysqli object or handle errors
     * 
     * @param string DB host
     * @param string DB user
     * @param string DB password
     * @param string DB name
     * @return object mysqli object
     */
    public function getmysqliObject(
        $db_host = null, 
        $db_user = null, 
        $db_pass = null, 
        $db_name = null
    )
    {
        // set the connection parameters - use either passed or default values
        if($db_host && $db_user && $db_pass && $db_name) {

            $this->setConnParams($db_host && $db_user && $db_pass && $db_name);

        } else {

            $this->setDefaultConnParams();
        }

        // initialize the mysqli object
        $this->mysqliObj = new mysqli($this->host, $this->user, $this->pass, $this->name);

        if (!$this->mysqliObj->connect_error) {

            // if connected successfully return the mysqli object
            return $this->mysqliObj;

        } else {

            // if error occured, handle it
            $this->handleError();
        }
    }

    /**
     * Handles the connection error
     * 
     */
    protected function handleError()
    {
        // this can be done only in development phase
        // in production you would put the code for logging errors here
        // or maybe just return false
        die(
            'Connect Error (' . 
            $this->mysqli->connect_errno . ') ' . 
            $mysqli->connect_error
        );
    }
}

I use the class this way:

// include the class file
include 'dbConnMysqli.php';
// initialize the connection object
$conn = new dbConnMySqli;
// this is now mysqli object, using test database
$db = $conn->getmysqliObject();

// define the query
$query = 'SELECT * FROM test';

// get the result
$result = $db->query($query);

// count the rows and display the count
$rowCount = $result->num_rows;
echo "Number of found rows: $rowCount <br />";

// display each row
while($row = $result->fetch_array(MYSQLI_ASSOC)) {

    foreach($row as $field) {

        echo "$field ";
    }
    echo '<br />';
}

$db->close();

// you can connect to another database
$db2 = $conn->getmysqliObject('somehostname', 'someusername', 'somepassword', 'somedatabase');

Considering the above, the Posts class should be something like:

class Posts {

    private $db;

    public function __construct($mysqli) {

        include 'dbConnMysqli.php';
        $conn = new dbConnMySqli;
        $this->db = $conn->getmysqliObject();
    }

    public function getPosts(){

        $query = "SELECT * FROM posts";
        $sql = $this->db->query($query);
        $result = $sql->fetch_assoc();
        $row = $result->num_rows;
        return $result;
    }
}

Do have any links or examples that show how mysqli_num_rows() & mysqli_fetch_assoc() works in OOP style.

There are good examples on php.net (see the Examples section after the definitions):

Class initialization
http://www.php.net/manual/en/mysqli.construct.php

Querying (includes code for class initialization)
http://www.php.net/manual/en/mysqli.query.php

Getting number of rows (includes code for class initialization and querying)
http://www.php.net/manual/en/mysqli-result.num-rows.php

php.net site at first look seems to be a bit unfriendly to new users due to a lot of technical information. But once you get used to it you find it the best resource for PHP. Always have look at the examples section and See also section. User comment can be interesting, too.

commented: Thanks for the resources! +10
Member Avatar for LastMitch

@broj1

you can not swallow a whole watermellon, you have to cut it in pieces

Nice idioms!

Thank You for taking your time to explaining an outline what I need to learn.

I will test the examples and work on it.

Member Avatar for LastMitch

@broj1

I just want to say Thanks for the example code for the OOP connection. It worked!

When I enter the data it's in the MYPHPADMIN so it fetch the data from the code you provided. I modify it little to table I have.

I think I'm gonna practice more with OOP with connections. It's fun.

Thanks for being patience and taking time to explain stuff!

I learn something new I appreciated your help!

Thanks

You are welcome.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.