Found problems:
- See
$con = new dbconn()
: To define properties of a class use one of the keywords public, protected, or private, static, constant, etc, followed by a normal variable declaration.
See Properties.
- See
$con = new dbconn()
: You can not create an object as part of a property definition. The property value must be a constant expression, not (for example) a variable, a property, or a function call. See Properties and Class Constants.
- See
$results = mysqli_query($conn, $query);
: Why are you receiving the error "mysqli_query() expects parameter 1 to be mysqli, null given in ..."? Because you're trying to reference $conn
, but it is neither defined as parameter in the definition of viewAuthor
method - like viewAuthor($conn) {...}
, nor correctly defined as a class property - if it was you'd have to reference it like this: $results = mysqli_query($this->conn, $query);
.
Now I'll try to give you two correct alternatives. But only the second one would be the recommended one. And I'll try to keep my explanations simple. Mind my naming and coding conventions, including the changed table name, the page names, the require
statement for the connection page, etc. And don't forget to change the database credentials in the page connection.php
with yours.
But, first, some recommendations:
- Don't use a class for connecting to the database. Just create an including file with the proper connectivity code (see
connection.php
).
- Create a constructor for each class needing to access the database and define a parameter for the connection object to be passed as argument. This passing step is called dependency injection.
- Use
require
instead of require_once
when you're including the connection.php
.
- Use the object oriented mysqli, not the procedural one. To each mysqli procedural function described on php.net there is an object oriented styled one too.
- Important: Use prepared statements instead of just directly querying the database by using
mysqli_query
. See this too.
- Important: Read this and this for properly applying error handling. E.g. to elegantly and safely get rid of
die(...)
, mysqli_error()
, etc.
- Important: Implement an autoloader, or, a lot better, use the Composer library. Implement namespaces too. Read PSR-1, PSR-2, PSR-4 and, in time, the other recommendations from PHP-FIG as well.
Alternative 1:
In the codes bellow it becomes obvious, why this alternative is not really a good one:
- An object of type
Author
- which should actually be the representation of only one table row - is used to fetch a collection of authors. Which are even fetched as a collection of objects of type stdClass
. Bad.
- An object of type
Author
is responsible for querying a database. Why should an object of type Author
have something to do with a database, actually? Bad.
connection.php:
<?php
// Db configs.
define('HOST', 'localhost');
define('PORT', 3306);
define('DATABASE', 'tests');
define('USERNAME', 'root');
define('PASSWORD', 'root');
/*
* Enable internal report functions. This enables the exception handling,
* e.g. mysqli will not throw PHP warnings anymore, but mysqli exceptions
* (mysqli_sql_exception).
*
* MYSQLI_REPORT_ERROR: Report errors from mysqli function calls.
* MYSQLI_REPORT_STRICT: Throw a mysqli_sql_exception for errors instead of warnings.
*
* @link http://php.net/manual/en/class.mysqli-driver.php
* @link http://php.net/manual/en/mysqli-driver.report-mode.php
* @link http://php.net/manual/en/mysqli.constants.php
*/
$mysqliDriver = new mysqli_driver();
$mysqliDriver->report_mode = (MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
/*
* Create a new db connection.
*
* @see http://php.net/manual/en/mysqli.construct.php
*/
$connection = new mysqli(HOST, USERNAME, PASSWORD, DATABASE, PORT);
Author.php:
<?php
class Author {
/**
* Database connection.
*
* @var mysqli
*/
private $connection;
/**
*
* @param mysqli $connection Database connection.
*/
public function __construct(mysqli $connection) {
$this->connection = $connection;
}
/**
* Get all authors.
*
* @return stdClass[] The authors list.
*/
public function getAllAuthors() {
/*
* The SQL statement to be prepared.
*
* @link http://php.net/manual/en/mysqli.prepare.php
*/
$sql = 'SELECT * FROM authors';
/*
* Prepare the SQL statement for execution.
*
* @link http://php.net/manual/en/mysqli.prepare.php
*/
$statement = $this->connection->prepare($sql);
/*
* Execute the prepared SQL statement.
* When executed any parameter markers which exist will
* automatically be replaced with the appropriate data.
*
* @link http://php.net/manual/en/mysqli-stmt.execute.php
*/
$statement->execute();
/*
* Get the result set from the prepared statement.
*
* NOTA BENE:
* Available only with mysqlnd ("MySQL Native Driver")! If this
* is not installed, then uncomment "extension=php_mysqli_mysqlnd.dll" in
* PHP config file (php.ini) and restart web server (I assume Apache) and
* mysql service. Or use the following functions instead:
* mysqli_stmt::store_result + mysqli_stmt::bind_result + mysqli_stmt::fetch.
*
* @link http://php.net/manual/en/mysqli-stmt.get-result.php
* @link https://stackoverflow.com/questions/8321096/call-to-undefined-method-mysqli-stmtget-result
*/
$result = $statement->get_result();
// Fetch the data into a stdClass[] array.
$rows = [];
while ($row = $result->fetch_object()) {
$rows[] = $row;
}
return $rows;
}
/**
* Get an author by id.
*
* @param int $authorId Author id.
* @return stdClass The author.
*/
public function getAuthorById(int $authorId) {
/*
* The SQL statement to be prepared. Notice the so-called markers,
* e.g. the "?" signs. They will be replaced later with the
* corresponding values when using mysqli_stmt::bind_param.
*
* @link http://php.net/manual/en/mysqli.prepare.php
*/
$sql = 'SELECT *
FROM authors
WHERE id = ?
LIMIT 1';
$statement = $this->connection->prepare($sql);
/*
* Bind variables for the parameter markers (?) in the
* SQL statement that was passed to prepare(). The first
* argument of bind_param() is a string that contains one
* or more characters which specify the types for the
* corresponding bind variables.
*
* @link http://php.net/manual/en/mysqli-stmt.bind-param.php
*/
$statement->bind_param('i', $authorId);
$statement->execute();
$result = $statement->get_result();
// Fetch the data into a stdClass object.
$row = $result->fetch_object();
return $row;
}
}
index.php:
<?php
require 'connection.php';
require_once 'Author.php';
$author = new Author($connection);
/*
* ================================
* Example 1: Get all authors.
* ================================
*/
// Get all authors.
$theAuthors = $author->getAllAuthors();
// Print the results.
echo '<b>Example 1: The whole authors list:</b>';
echo '<br/></br/>';
foreach ($theAuthors as $theAuthor) {
echo $theAuthor->id . ' - ' . $theAuthor->first_name . ', ' . $theAuthor->last_name . '<br/>';
}
echo '<br/><hr/><br/>';
/*
* ================================
* Example 2: Get an author by id.
* ================================
*/
// Get an author by id.
$theAuthor = $author->getAuthorById(2);
// Print the results.
echo '<b>Example 2: One selected author:</b>';
echo '<br/><br/>';
echo $theAuthor->id . ' - ' . $theAuthor->first_name . ', ' . $theAuthor->last_name . '<br/>';
Alternative 2:
Let's change the code above to make more semantical and structural sense. For this, think of an object of type Author
as an entity whose only purpose is to hold the characteristics of an author and to manipulate them on demand. This type of objects are known as domain objects and are only responsible with the business logic. See this answer. So, an Author
object should have nothing to do with a database, or with any other persistence layer (session, file system, etc). It should actually be completely unaware of the place and fashion in which its properties are fetched.
The responsibility of querying the database, fetching the author characteristics (e.g. the field values of a specific row in the authors
table) and assigning them to an Author
object should therefore be deferred to a so-called data mapper.
So, the code in your case would look like this:
connection.php:
The same as above.
Author.php:
<?php
class Author {
/**
* Author id.
*
* @var int
*/
private $id;
/**
* First name.
*
* @var string
*/
private $firstName;
/**
* Last name.
*
* @var string
*/
private $lastName;
/**
* Get the name as 'John, Doe'.
*
* @return string The name.
*/
public function getName() {
return $this->firstName . ', ' . $this->lastName;
}
/**
* Get the id.
*
* @return int
*/
public function getId() {
return $this->id;
}
/**
* Set the id.
*
* @param int $id Id.
* @return $this
*/
public function setId($id) {
$this->id = $id;
return $this;
}
/**
* Get the first name.
*
* @return string
*/
public function getFirstName() {
return $this->firstName;
}
/**
* Set the first name.
*
* @param string $firstName First name.
* @return $this
*/
public function setFirstName($firstName) {
$this->firstName = $firstName;
return $this;
}
/**
* Get the last name.
*
* @return string
*/
public function getLastName() {
return $this->lastName;
}
/**
* Set the last name.
*
* @param string $lastName Last name.
* @return $this
*/
public function setLastName($lastName) {
$this->lastName = $lastName;
return $this;
}
}
AuthorMapper.php:
<?php
require_once 'Author.php';
class AuthorMapper {
/**
* Database connecton.
*
* @var mysqli
*/
private $connection;
/**
* Authors collection.
*
* @var Author[]
*/
private $authorsCollection = [];
/**
*
* @param mysqli $connection Database connection.
*/
public function __construct(mysqli $connection) {
$this->connection = $connection;
}
/**
* Get all authors.
*
* @return array Authors list.
*/
public function getAllAuthors() {
$sql = 'SELECT * FROM authors';
$statement = $this->connection->prepare($sql);
$statement->execute();
$result = $statement->get_result();
// Fetch the data into a stdClass[] array.
$rows = [];
while ($row = $result->fetch_object()) {
$rows[] = $row;
}
// Fill and return the authors collection.
return $this->createAuthorsCollection($rows);
}
/**
* Get an author by id.
*
* @param int $authorId Author id.
* @return Author The author.
*/
public function getAuthorById(int $authorId) {
$sql = 'SELECT *
FROM authors
WHERE id = ?
LIMIT 1';
$statement = $this->connection->prepare($sql);
$statement->bind_param('i', $authorId);
$statement->execute();
$result = $statement->get_result();
// Fetch the data into a stdClass object.
$row = $result->fetch_object();
// Crete and return an Author object.
return $this->createAuthor($row);
}
/**
* Create an Author from the given stdClass object:
*
* - Create an Author object.
* - Assign a property value to the Author object for each property of the given stdClass object.
* - Return the Author object.
*
* @param stdClass $row The row object.
* @return Author The author.
*/
public function createAuthor(stdClass $row) {
$author = new Author();
$author
->setId($row->id)
->setFirstName($row->first_name)
->setLastName($row->last_name)
;
return $author;
}
/**
* Create an Author[] list from the given stdClass[] list:
*
* - Iterate through the given stdClass[] list.
* - Create an Author object for each list item.
* - Assign a property value to the Author object for each property of the given stdClass object.
* - Push the Author object to the authors collection.
* - Return the content of the collection.
*
* @param array $rows Rows list as a stdClass[] list.
* @return Author[] The authors list as an Author[] list.
*/
public function createAuthorsCollection(array $rows = []) {
foreach ($rows as $row) {
$this->authorsCollection[] = $this->createAuthor($row);
}
return $this->authorsCollection;
}
}
index.php:
<?php
require 'connection.php';
require_once 'AuthorMapper.php';
// Create an author data mapper.
$authorMapper = new AuthorMapper($connection);
/*
* ================================
* Example 1: Get all authors.
* ================================
*/
// Get all authors.
$authors = $authorMapper->getAllAuthors();
// Print the results.
echo '<b>Example 1: The whole authors list:</b>';
echo '<br/></br/>';
foreach ($authors as $author) {
echo $author->getId() . ' - ' . $author->getName() . '<br/>';
}
echo '<br/><hr/><br/>';
/*
* ================================
* Example 2: Get an author by id.
* ================================
*/
// Get an author by id.
$author = $authorMapper->getAuthorById(2);
// Print the results.
echo '<b>Example 2: One selected author:</b>';
echo '<br/><br/>';
echo $author->getId() . ' - ' . $author->getName();
As you see, an AuthorMapper
queries the database and fetches the table rows into a collection of objects of type stdClass
. Then it maps these objects to corresponding objects of type Author
, whose properties are printed, or used by certaing methods (like getName()
) in order to achieve certain results.
The output of each alternative:

Used data:
CREATE TABLE `authors` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(100) DEFAULT NULL,
`last_name` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `authors` (`id`, `first_name`, `last_name`)
VALUES
(1,'Johny','John'),
(2,'Samantha','Sam'),
(3,'Maria','Mar');
List of resources: