Just trying to get my head around OOP. I have been told that I am doing the script below wrong. I was previously trying to call a method from the database class. When really the database class should only be dealing with database stuff. So I have now created an html_class.php where I believe I need to access the database class and then output the html via this class?.
The method I am trying to call on the index.php is the getBlogPost()method located in the html_class.php file. I am trying to call this using echo $htmlObject->getBlogPosts();
I am assuming this is the proper way to go about doing this?
I am currently getting the following errors:
Notice: Undefined variable: db_login_info in C:\xampp\htdocs\xampp\oop\CMS\classes\html_class.php on line 14
Fatal error: Cannot access private property database::$objDbConn in C:\xampp\htdocs\xampp\oop\CMS\classes\html_class.php on line 15
index.php
<?php
require_once("includes/header.php");
require_once("includes/footer.php");
require_once("classes/database_class.php");
require_once("classes/blog_post_class.php");
require_once("classes/html_class.php");
require_once("conf/config.php");
$header = new header();
// createHeader( Title | Description | Keywords)
echo $header->createHeader('Home - Nissan Skyline GTR Blog', 'This is a blog site about the Nissan GTR', 'Nissan, GTR, R35');
$dbObject = new database($db_login_info);
$htmlObject = new makeHTML();
?>
<div id="container">
<div id="top_nav">
Admin Login
</div>
<div id="header"></div>
<div id="nav">
<ul>
<li>Home</li>
<li>Create Blog</li>
<?php
$sql = "SELECT * FROM create_page";
echo $dbObject->createNavigation($sql);
?>
</ul>
</div>
<div id="content_area">
<?php
echo $htmlObject->getBlogPosts(); // Calling the getBlogPost function located in the html_class.php
// echo $dbObject->getBlogPosts();
?>
</div>
<?php
$footer = new footer();
echo $footer->createFooter();
?>
database_class.php
<?php
class database {
private $objDbConn;
function __construct($db_login_info){
$this->objDbConn = new mysqli($db_login_info['host'], $db_login_info['username'],
$db_login_info['password'], $db_login_info['database']);
if (mysqli_connect_errno()) {
die("Database connection failed". mysqli_connect_error());
}
}
// I was previoulsy calling this method below on the index.php page and it was working great
// function getBlogPosts(){
// $objRes = mysqli_query($this->objDbConn, "SELECT * FROM `blog_posts` ORDER BY id DESC");
// if(mysqli_errno($this->objDbConn)) {
// die("Failed query: $strSql". $this->objDbConn->error);
// }
// $allrows ='';
// while ($row = mysqli_fetch_array($objRes)) {
// $time = strtotime($row['date']);
// $my_format = date("m/d/y # g:ia", $time);
// $allrows .= '<div id="blog_post">';
// $allrows .= '<h2 id="blog_title">'.$row['title'].'</h2>';
// $allrows .= '<h5> Posted on the '.$my_format.'</h5>'."<br>";
// $allrows .= '<div id="blog_content">'.nl2br($row['content']).'</div>'."<br>";
// $allrows .= '<b>ID:</b>'.$row['id'].' Delete</div>';
// };
// return $allrows;
// }
?>
html_class.php
<?php
require_once("includes/header.php");
require_once("includes/footer.php");
require_once("classes/database_class.php");
require_once("classes/blog_post_class.php");
require_once("classes/html_class.php");
require_once("conf/config.php");
class makeHTML {
function getBlogPosts(){
$dbObject = new database($db_login_info); // This is where the Notice: Undefined variable: db_login_info is happening
$objRes = mysqli_query($dbObject->objDbConn, "SELECT * FROM `blog_posts` ORDER BY id DESC");
if(mysqli_errno($dbObject->objDbConn)) {
die("Failed query:". $dbObject->objDbConn->error);
}
$allrows ='';
while ($row = mysqli_fetch_array($objRes)) {
$time = strtotime($row['date']);
$my_format = date("m/d/y # g:ia", $time);
$allrows .= '<div id="blog_post">';
$allrows .= '<h2 id="blog_title">'.$row['title'].'</h2>';
$allrows .= '<h5> Posted on the '.$my_format.'</h5>'."<br>";
$allrows .= '<div id="blog_content">'.nl2br($row['content']).'</div>'."<br>";
$allrows .= '<b>ID:</b>'.$row['id'].' Delete</div>';
};
return $allrows;
}
}
?>
config.php
<?php
// Database login details below
$db_login_info = array(
'host'=>'localhost',
'username'=>'root',
'password'=>'',
'database'=>'cms'
);
?>
Updated html_class.php
<?php
require_once("includes/header.php");
require_once("includes/footer.php");
require_once("classes/database_class.php");
require_once("classes/blog_post_class.php");
require_once("classes/html_class.php");
require_once("conf/config.php");
class makeHTML {
private $database;
public function __construct(database $database){
$this->database = $database;
}
function getBlogPosts(){
$objRes = mysqli_query($this->database, "SELECT * FROM `blog_posts` ORDER BY id DESC");
if(mysqli_errno($this->database)) {
die("Failed query:". $this->database->error);
}
$allrows ='';
while ($row = mysqli_fetch_array($objRes)) {
$time = strtotime($row['date']);
$my_format = date("m/d/y # g:ia", $time);
$allrows .= '<div id="blog_post">';
$allrows .= '<h2 id="blog_title">'.$row['title'].'</h2>';
$allrows .= '<h5> Posted on the '.$my_format.'</h5>'."<br>";
$allrows .= '<div id="blog_content">'.nl2br($row['content']).'</div>'."<br>";
$allrows .= '<b>ID:</b>'.$row['id'].' Delete</div>';
};
return $allrows;
}
}
Update database_class.php
class database {
public $objDbConn;
function __construct($db_login_info){
$this->objDbConn = new mysqli($db_login_info['host'], $db_login_info['username'],
$db_login_info['password'], $db_login_info['database']);
if (mysqli_connect_errno()) {
die("Database connection failed". mysqli_connect_error());
}
}
?>
fetchall method in database_class.php:
function fetchall($sql) {
$query = mysqli_query($this->objDbConn, $sql);
if ($this->objDbConn->connect_errno) {
die("Database connection failed with message: " . $objDbConn->connect_error);
}
}
You should use "Dependency Injection" to give your makeHtml class the database object.
Add a __construct method to your makeHtml class:
class makeHtml
{
private $database;
public function __construct(database $database)
{
$this->database = $database;
}
When you instantiate your makeHtml class:
$htmlObject = new makeHTML($dbObject);
Then inside your class, instead of creating a new database object (and a new connection every time) you can just refer to your database object with $this->database.
Further note to your case above, you will need to make the $objDbConn variable in the database class public so that you can access that variable in the other class. However, it would be "good practice" to have a method within your database class that deals with performing queries and returning the result. Ideally you should end up with something like:
$sql = 'SELECT * FROM `blog_posts` ORDER BY id DESC';
$allRows = $this->database->fetchAll($sql);
That will appear in your makeHtml class.
Okay, a few different things are going on with your code.
For starters, you are mixing procedural and object-oriented versions of MySQLi. The fact that you are using MySQLi is a big plus instead of going with the old deprecated version of MySQL. However, you need to pick between procedural or OOP, and then stick with it.
As for your error messages. You are getting the notice about $db_login_info because it does not exist in the getBlogPosts() method. When you are inside of a method your variable scope becomes limited. Meaning that variables declared outside of it are not visible within the method unless they are passed in as parameters.
The second message is about class scope. Your variable $dbObjConn is declared as private, which is fine, but you can only access a private variable from within the same class. If you declare it public then you can access it the way you are.
So here are some modifications I can suggest making to your code. Having a database class isn't a bad thing, it is easier to create a connection as an object and then pass that object around to other classes that need it. But, when you do this you should not mix the procedural versions of MySQLi with the OOP version. (I recommend you stick with the OOP version).
Your database_class.php could look something like this:
class database {
private $objDbConn;
function __construct($db_login_info){
$this->objDbConn = new mysqli($db_login_info['host'], $db_login_info['username'],
$db_login_info['password'], $db_login_info['database']);
//This is where you are using the procedural interface
//if (mysqli_connect_errno()) {
// die("Database connection failed". mysqli_connect_error());
// }
//}
//Use the OOP version instead
if ($this->objDbConn->connect_errno) {
die("Database connection failed with message: " . $this->objDbConn->connect_error);
}
}
//Keep populating this class with more stuff. Like:
public function getDB() {
return $this->dbObjConn; //use this method to access your private database variable from outside the class
}
}
The html_class.php file could use some love as well:
class makeHTML {
private $database; //Here is a place for your shiny database object.
public functon __construct($database) {
$this->database = $database;
}
public function getBlogPosts() {
$dbObject = $this->database->getDB();
$objRes = $dbObject->query($dbObject->objDbConn, "SELECT * FROM `blog_posts` ORDER BY id DESC");
if($dbObject->errno) {
die("Failed query:". $dbObject->error);
}
$allrows ='';
while ($row = $objRes->fetch_array()) {
$time = strtotime($row['date']);
$my_format = date("m/d/y # g:ia", $time);
$allrows .= '<div id="blog_post">';
$allrows .= '<h2 id="blog_title">'.$row['title'].'</h2>';
$allrows .= '<h5> Posted on the '.$my_format.'</h5>'."<br>";
$allrows .= '<div id="blog_content">'.nl2br($row['content']).'</div>'."<br>";
$allrows .= '<b>ID:</b>'.$row['id'].' Delete</div>';
};
return $allrows;
}
//Again, keep adding more to this class as you see fit....
}
Then to put all of this together, your calling code would look something like:
<?php
include "config.php";
$myDatabase = new database($db_login_info);
$html = new makeHTML($myDatabase);
$posts = $html->getBlogPosts();
print($posts);
?>
you cannot use private member of object. Instead you could use method or make member public.
Also instead of creating connection object every time you should create connection object in config file and include this file once.
Related
This question already has answers here:
Why does this PDO statement silently fail?
(2 answers)
Closed 4 years ago.
I want to show all the records from the DB on my website, it's a PDO built website. I want it to show all the records so you can see what's in the DB.
This is how my DB looks like
The connection is set up in a different document called config.php
<?php
date_default_timezone_set('Europe/Amsterdam');
error_reporting(E_ALL & ~ E_DEPRECATED);
ini_set('display_errors', 'ON');
$CONFIG = array();
$CONFIG['root'] = '/home/tom/public_html';
$CONFIG['rootwebsite'] = '/home/tom/public_html';
$CONFIG['website'] = 'https://###';
$CONFIG['dbhost'] = 'localhost';
$CONFIG['dbuser'] = '####';
$CONFIG['dbpass'] = '####';
$CONFIG['dbdatabase'] = 'tom';
?>
This is the code I have in a php document and tried using. The problem is it won't show anything on my website (this is a different file than the file my website is):
<?php
class Forum {
private $dbh; //dbh = database handler.
public function __construct($database) {
$this->dbh = $database;
}
public function getForum() {
$getTopic = $dbh->prepare("SELECT * FROM topics ORDER BY id DESC");
$getTopic->execute();
$topics = $getUTopic->fetchAll();
foreach ($topics as $topic) {
echo $topic['onderwerp'] . '<br />';
}
}
}
You are not calling the right $connection variable. It should be $this->dbh
$getTopic = $this->dbh->prepare("SELECT * FROM topics ORDER BY id DESC");
Also you are mixing the variables after execute(). You should use easy to remember variables.
public function getForum() {
try {
$getTopic = $this->dbh->prepare("SELECT * FROM topics ORDER BY id DESC");
$getTopic->execute();
$topics = $getTopic->fetchAll();
foreach ($topics as $topic) {
echo $topic['onderwerp'] . '<br />';
}
} catch (PDOException $pdoEx) {
echo $pdoEx->getMessage();
exit;
} catch (Exception $ex) {
echo $ex->getMessage();
exit;
}
}
Also since you are not passing any variable to your query, there is no point of using prepare(). Just call query() instead.
For error reporting add,
error_reporting(E_ALL); #place at the top of the script
Also you should consider using a proper IDE like PHPstorm or Netbeans, as they would easily point out unsed variables
As suggested by #adpro, here is a link, to help with debugging
I cannot for the life of me figure out why the DeleteTask function will not work, when it is almost the same as RetrieveTask; only called in different files.
Now:
src/controller/RetrieveTask:
prepares a PDO database query, and passes it to src/view/DisplayTask.php, which uses a for each-loop to echo the rows and an <a> element linking to src/redir/DeleteAndReturn.php.
This file simply executes src/controller/DeleteTask.php and src/controller/ReturnToIndex.php.
The file code and order is as follows:
RetrieveTask
<?php
function RetrieveTask($db)
{
$sql = 'SELECT * FROM task';
return $db->query($sql);
}
?>
Which gets passed to DisplayTask:
<?php
function DisplayTask($db)
{
foreach (RetrieveTask($db) as $row)
{
echo "<li>" . $row['tsk-name'] . "<br>" . $row['tsk-desc'] . "<a id=".$row['id']." class='btn btn-danger' href='/todo/redir/DeleteAndReturn.php'>Delete</a>" . "</li>";
}
}
?>
Which get passed to index.php in the /todo/home directory. All I need to do is call DisplayTask($DbHandler) Where $DbHandler is an instant of the db class.
Now for src/controller/DeleteTask.php:
<?php
function DeleteTask($db)
{
echo "Delete";
$sql = ' DELETE FROM task where id= 2 ';
return $db->query($sql);
}
?>
and src/controller/ReturnToIndex.php:
<?php
function ReturnToIndex()
{
header('Location: /todo/home');
}
?>
Leads to redir/DeleteAndReturn.php
<?php
include_once('../src/model/db/DbConnect.php');
include_once('../src/controller/DeleteTask.php');
include_once('../src/controller/ReturnToIndex.php');
$DbHandler = new DbConnect();
DeleteTask($DbHandler);
$DbHandler->CloseConnection();
ReturnToIndex();
?>
I've tried passing the item id as a get parameter in a query string. Deleting all tables. Manually selecting the id. I can't get it to work. Any help would be much appreciated. I googled and looked up documentation for hours. I feel like it is something exceedingly simple that just went way over my head.
Full code is here: https://github.com/liengesbor.
As maxim_039 suggested, I changed how a variable array was passed to the DB construct. Somehow this fixed the issue.
function __construct()
{
- parent::__construct('mysql:host=localhost;dbname=todo;', 'root', 'alexel', array ('$opt'));
+ parent::__construct('mysql:host=localhost;dbname=todo;', 'root', 'alexel', $this->opt);
echo "Connected to Database";
}
Here is the database code:
<?php
// Connect to the database using PDO and MySQL
class DbConnect extends PDO
{
protected $dsn = "mysql:host=localhost;dbname=todo;";
protected $dbPassword = 'alexel';
protected $dbUsrName = 'root';
protected $opt = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
);
function __construct()
{
parent::__construct('mysql:host=localhost;dbname=todo;', 'root', 'alexel', $this->opt);
echo "Connected to Database";
}
function CloseConnection()
{
$this->DbConnection = null;
}
}
?>
i'm trying to call getMensClothing() function from function.php to header.php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "khaki";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
function getMensClothing(){
global $conn;
$sql = "SELECT * FROM men_clothing";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "<li><a href='#' class='hvr-grow'>". $row['men_clo_items']." </a></li>";
}
}
}
header.php file looks like this
<?php include 'functions.php'; ?>
<?php
echo'
<div class="col-sm-2"><br>
<p> <b>Men\'s Clothing</b></p>
<ul>
'.getMensClothing().'
</ul>
</div>'
?>
function is called but the items aren't displayed where it has to everything is show at the top of the page . How to display the items inside the div ??
Use below Code
$html = "";
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$html .= "<li><a href='#' class='hvr-grow'>". $row['men_clo_items']."</a></li>";
}
}
return $html;
into your function.php file
create a class like
class support{
//inside goes codes and functions
}
while calling into another file.
include it above file then create
$a=new support()
$a->functionname();
this should do the trick
What happens is that you use echo with parameters, that are evaluated to be printed.
You use concatenation with your arguments to echo.
You have one parameter contructed with the concatenation of three arguments.
The result of this concatenation is printed. One of these arguments is the returned value of the getMensClothing() function.
During the evaluation of getMensClothing() you print some data.
Consequently, the data printed in your function getMensClothing() gets printed before the end of the call to echo statement in header.php.
As other people pointed out, you should reconsider your technique as your code could be more easy to use if you separate the job of retrieving and constructing your data and the job of displaying it. Have a look to MVC for instance.
This question already has answers here:
Executing mysqli_query inside a function
(2 answers)
Closed 7 years ago.
I'm having some problems performing a mysql query inside a php function. The error I am getting is
Notice: Undefined variable: link in C:\path\api\inc\restFunctions.php on line 16
There are several files calling each other so I will attempt to outline the necessary information.
URL Accessed:
localhost/serverList/api/rest.php?action=allServers
serverList/api/rest.php
<?php
include 'inc/restFunctions.php';
$possibleCalls = array('allServers','allEnvs','allTypes','false');
if(isset($_GET['action'])){
$action = $_GET['action'];
}
else{
$action = 'false';
}
if(in_array($action,$possibleCalls)){
switch ($action){
case 'allServers':
$return = allServers();
break;
case 'allEnvs':
$return = allEnvs();
break;
case 'allTypes':
$return = allTypes();
break;
case 'false':
$return = falseReturn();
break;
}
}
serverList/api/inc/restFunctions.php
<?php
include ('inc/config.php');
function allServers(){
$serverInfoQuery = "SELECT * FROM servers"
$allServerResults = $link->query($serverInfoQuery);
$json = array();
while($row = $allServerResults->fetch_assoc()){
$json[]['serverID'] = $row['serverID'];
$json[]['environment'] = $row['environment'];
$json[]['type'] = $row['type'];
$json[]['serverIP'] = $row['serverIP'];
$json[]['serverDescription'] = $row['serverDescription'];
$json[]['serverCreatedBy'] = $row['serverCreatedBy'];
$json[]['serverCreatedDtTm'] = $row['serverCreatedDtTm'];
$json[]['serverUpdatedBy'] = $row['serverUpdatedBy'];
$json[]['serverUpdatedDtTm'] = $row['serverUpdatedDtTm'];
}
$jsonResults = json_encode($json);
return $jsonResults;
}
?>
serverList/api/inc/config.php
<?php
$host = 'localhost';
$user = 'userName';
$password = 'password';
$database = 'database';
$link = new mysqli($host, $user, $password, $database);
if (mysqli_connect_errno()) {
exit('Connect failed: '. mysqli_connect_error());
}
?>
I have verified that the query being called works. I also verified that the connection info (masked above) works by using a different page of this software that queries the db.
I'm assuming I must have missed a quote or paren somewhere, but I'm baffled as to where it might be.
The problem is with PHP variable scoping. Add this line inside of allServers() function before you refer to the $link variable for the first time:
global $link;
See more here:
http://php.net/manual/en/language.variables.scope.php
In my opinion using global variables is not a good solution. You might override $link ($link is rather usual name for a variable you may be using for another purposes) variable in some scope by accident, resulting in lot's of confusion and difficult debugging.
Just pass it as a function parameter - much cleaner and easier to read:
function AllServers($link) {
$serverInfoQuery = "SELECT * FROM servers";
$allServerResults = $link->query($serverInfoQuery);
//More PHP code
}
if(in_array($action,$possibleCalls)){
switch ($action){
case 'allServers':
$return = allServers($link);
break;
}
}
To be honest, even better solution would be using some generic classes/functions to establish your mysql connection like so:
class DB {
private static $link = null;
public static function getConnectionResource() {
//In that way we "cache" our $link variable so that creating new connection
//for each function call won't be necessary
if (self::$link === null) {
//Define your connection parameter here
self::$link = new mysqli($host, $user, $password, $database);
}
return self::$link;
}
}
function getAllServers() {
$link = DB::getConnectionResource();
//Preform your query and return results
}
Use global variable
function allServers(){
global $link
...
...
...
... your code follows
Already tearing my hairs out for a couple of days. There is not much left of them ;-)
I am experiencing a strange problem when I want to bind a service to a button or something else:
files:
- CDPC.php
<?php
require_once ('VOcdpc.php');
class CDPC {
var $username = "root";
var $password = "";
var $server = "localhost";
var $port = "3306";
var $databasename = "xoffercommon";
var $tablename = "tblcity";
var $connection;
public function __construct() {
$this->connection = mysqli_connect(
$this->server,
$this->username,
$this->password,
$this->databasename,
$this->port
);
mysqli_set_charset($this->connection,'utf8');
$this->throwExceptionOnError($this->connection);
}
public function getCDPC($cityID) {
$con = mysql_connect("localhost","root","");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("xoffercommon", $con);
$cdpc_Id = new Vocdpc();
$cdpc_Id->id_cdpc = 1;
$cdpc_Id->city_Id=$cityID;
$result_prov = mysql_query("SELECT tblProvence_Id FROM tblCity WHERE Id = " . $cityID);
$row = mysql_fetch_array($result_prov);
$cdpc_Id->provence_Id=intval($row['tblProvence_Id']);
$result_dist = mysql_query("SELECT tblDistrict_Id FROM tblProvence WHERE Id = " . $cdpc_Id->provence_Id);
$row = mysql_fetch_array($result_dist);
$cdpc_Id->district_Id=intval($row['tblDistrict_Id']);
$result_coun = mysql_query("SELECT tblCountry_Id FROM tblDistrict WHERE Id = " . $cdpc_Id->district_Id);
$row = mysql_fetch_array($result_coun);
$cdpc_Id->country_Id=intval($row['tblCountry_Id']);
return $cdpc_Id;
mysql_close($con);
}
private function throwExceptionOnError($link = null) {
if($link == null) {
$link = $this->connection;
}
if(mysqli_error($link)) {
$msg = mysqli_errno($link) . ": " . mysqli_error($link);
throw new Exception('MySQL Error - '. $msg);
}
}
}
?>
VOcpdc.php
<?php
class VOcdpc
{
public $id_cdpc;
public $country_Id;
public $district_Id;
public $provence_Id;
public $city_Id;
// explicit actionscript class
var $_explicitType = "Vocdpc";
}
?>
In flex builder
I can add the services to the Data Services panel but I have two strange things:
1) when I want to configure the return type he doesn't let me create a new ValueObject type, I only get the bottom datagrid which states: Properties returned by the operation: Property: country_Id, provence_Id, city_Id, id_cdpc, district_Id with the related values on the right side. Why can't I create a new data type on the top?
2) When I accept this and want to add the service call to a button (drag&drop) I get the following error: Error occurred while generating code. Make sure that there are no compiler eroors and try again after reopening the file. Componentn type services.cdpc.CDPC not found...
(ps: When I perform a Test Operation everything seems to be ok, I get the expected output values)
this is the class included in the main cdpc.php file, the post drops it apparently, so here is the VOcpdc file:
// explicit actionscript class
var $_explicitType = "Vocdpc";
}
?>