I'm trying to connect to a database using a config file that is a part of my Joomla website.
My config file looks like:
<?php
class JConfig {
public $dbtype = 'mysqli';
public $host = 'localhost';
public $user = 'xxxx';
public $password = 'xxxx';
public $db = 'xxxx';
public $dbprefix = 'xxxx_';
}
Below is the page that includes the configuration file:
<?php
include("configuration.php");
// Create connection
$conn = mysqli_connect($host, $user, $password, $db);
// Check connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
$sql = "SELECT id, navn, email FROM XXXX";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
// Output data of each row
while ($row = mysqli_fetch_assoc($result)) {
echo "id: " . $row["id"]. " - Name: " . $row["navn"]. " " . $row["email"]. "<br>";
}
} else {
echo "0 results";
}
mysqli_close($conn);
However, I cannot connect to the database as I get the following error message:
Connection failed: Access denied for user ''#'localhost' (using password: NO)
I think the issue might be because the config file has public in front of all the variables.
Question: How can I get around keeping the variables public, since the Joomla script needs them, but avoid the error?
Assuming the path is correct, do this instead:
require_once "configuration.php";
$Conf = new JConfig;
// Create connection
$conn = mysqli_connect($Conf->host, $Conf->user, $Conf->password, $Conf->db);
In simple terms the config file contains an class named JConfig, so you must instantiate that class and access it's public properties.
other stuff
Use require not include, as this config is needed for the rest of this script to work and include will just ignore missing files. Require will produce an error, and let you know what is wrong when the file is missing/no found. Further, use require once because you cannot redefine the same class multiple times.
PS. you don't need the () on include/require, and the same is true for construct with no arguments... (I'm lazy so I don't like to type those things out)
Enjoy!
Related
For Instance consider this standard database connection php file.
db_conn.php
<?php
$servername = "localhost";
$username = "root";
$password = "Yash123";
// Create connection
$conn = new mysqli($servername, $username, $password);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
?>
If connected successfully it is shows that result onto the website.
What I'd need it to do is not show up on the html but be there in the file so I can test the file executing in the CLI(Command Line Interface) of PHP.
I am using require_once(); in the index file.
uncomment the echo line. or use php's error_log('Connected Successfully');. this would log that the connection was successful. This would hide output from your html and log the string passed as parameter to your error_log file
One could easily dispense with the echo statement and instead return the connection object upon success. This would entail revising the OP code so that it becomes the contents of a database connect function. This idea I gleaned from binpress.com and include suggestions from the Manual, too:
<?php
/* Assuming that user name,password and database name are
credentials that come from a file outside of the
document root for security. */
function db_connect() {
static $conn;
$servername = "localhost";
if ( !isset( $conn ) ) {
// load and parse file containing credentials:
$config = parse_ini_file('../config.ini');
// Create connection
$conn = new mysqli( $servername, $config['username'],$config['password'],
$config['dbname']);
// Check connection
if ($conn->connect_error) {
die('Connect Error (' . $conn->connect_errno . ') '
. $conn->connect_error);
}
// Connected successfully
return $conn;
}
This is a general example.
The application has 3 files.
conn.inc.php -- setting up the database connection
<?php
$db_host = "localhost";
$db_username = "root";
$db_pass = "";
$db_name = "hmt";
$conn = new mysqli($db_host, $db_username, $db_pass, $db_name);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
?>
func.inc.php -- file including functions
<?php
function load_module($module_name){
$sqlCmd = "SELECT content FROM modules WHERE name='$module_name' LIMIT 1";
$result = $conn->query($sqlCmd);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$module_footer = $row["content"];
}
}else {
echo 'Error while loading module '.$module_name;
}
return $result;
$result->free_result();
}
?>
index.php -- the main page to display content
<?php
include 'conn.inc.php';
include 'func.inc.php';
if (!isset($_GET['page_name'])) { // if page_name is not set then reset it to the homepage
$page_name = 'module_footer';
}else{
$page_name = $_GET['module_footer'];
}
$module_content = load_module($page_name);
echo $module_content;
?>
Now my goal was to include functions inside the func.inc.php file and database into conn.inc.php, so as to keep separate and easier to read in the future.
My problem now is that the $conn variable declared in conn.inc.php cannot be used inside the function and it can't get my head around how to use it. I even tried using GLOBALS with no success.
The error for the files is this:
Notice: Undefined variable: conn in ./func.inc.php on line 4
Fatal error: Call to a member function query() on a non-object in ./func.inc.php on line 4
Which (I assume) is because the $conn variable is not in a global scope.
Now my question is. How can I keep the nested files but have the functions working? Is there a mistake in my approach or is it not possible to use a nested call to a mysql object?
Eventually you'll want to get into object-oriented coding but for now lets make what you have a little prettier.
When including files, you'll want to avoid things like global variables. They sound great, but end up being a pain when handling scope. So instead include a set of functions to call.
conn.inc.php
function getConnection(){
$db_host = "localhost";
$db_username = "root";
$db_pass = "";
$db_name = "hmt";
$conn = new mysqli($db_host, $db_username, $db_pass, $db_name);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
return $conn;
}
Then function.inc.php
<?php
function load_module($module_name){
$sqlCmd = "SELECT content FROM modules WHERE name='$module_name' LIMIT 1";
//Here is where we get our database connection.
$conn = getConnection();
$result = $conn->query($sqlCmd);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$module_footer = $row["content"];
}
}else {
echo 'Error while loading module '.$module_name;
}
return $result;
$result->free_result();
}
And finally finish up with your index page the way it is. So now, any page that wants a database connection will need to include the conn.inc.php and simply call getConnection() to get a mysqli connection object.
Think of your program as being a series of individual functions working together. And eventually you'll get to it being a series of objects working together. Nothing should be just floating off in global space. Try to encapsulate everything in some sort of function or object to be called over and over with consistent results.
You'd have to do something like this:
$conn = '';
function connect() {
global $conn;
... do db stuff
}
But this is usually bad practice. A more common method is to use a singleton object to "carry" your db handle, and you new that singleton everywhere you need to do DB operations.
function do_something() {
$conn = new DBSingleton();
... do db stuff
}
I created a class to access my database. The simplified class is following (I named it dbaccess.php)
class dbaccess {
function read($db) {
$con = mysqli_connect($db);
if (mysqli_connect_errno()){
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT * FROM equipment");
while($row = mysqli_fetch_array($result)){
$print = $print . $row['ID'] . " " . $row['name'] . " " . $row['new_price'] . " " . $row['residual_value'] . "<br>";
}
echo $print;
mysqli_close($con);
}
}
To access the class, I use this code
include './dbaccess.php';
//define db address
$add = '"localhost","myuser","mypassword","mydbname"';
$db = new dbaccess;
$db->read($add);
This code resulting
Failed to connect to MySQL: Unknown MySQL server host '"localhost","myuser","mypassword","mydbname"'(2)
I don't know how to fix it, can anyone here help me?
You're passing a single string to mysqli_connect. You need to pass "localhost", "myuser",... as separate variables.
http://php.net/manual/en/function.mysqli-connect.php
I have something similar with yours, download my files from dropbox and have a look inside
DB Connect
class dbaccess {
function read($db) {
$con = mysqli_connect($server, $user, $password, $dbname);
(...)
Then in your code, you should divide the parameters.
include './dbaccess.php';
//define db address
$db = new dbaccess;
$db->read("localhost","myuser","mypassword","mydbname");
REF
It's probably a better idea to store your host, username, password and database in separate variables like this:
$host = "localhost";
$user = "myuser";
$pass = "mypassword";
$data = "mydbname";
$db = new dbaccess(); // <-- It's good practice to use parentheses in the constructor statement.
$db->read($host,$user,$pass,$data);
And then the implementation of your dbaccess class could be more like this:
$con = mysqli_connect($host,$user,$pass,$data);
This is because the mysqli_connect function takes the host, username, etc. as separate parameters, not as a single string.
If I try to open this simple file in my Browser:
<?php
require_once 'classes/settings.php';
class Mysql {
private $conn;
function __construct() {
$this->conn = new mysqli (DB_SERVER,DB_USER,DB_PASSWORD,DB_MEMBER) or die('There was a problem connecting to the database.');
if ($this->conn->connect_errno) {
echo "Failed to connect to MySQL: (" . $this->conn->connect_errno . ") " . $this->conn->connect_error;
}
//echo $mysqli->host_info . "\n";
}
function verify_Username_and_Pass($un, $pwd) {
$query = "SELECT *
FROM users
WHERE username = ? AND password = ?
LIMIT 1";
if($stmt = $this->conn->prepare($query)) {
$stmt->bind_param('ss',$un,$pwd);
$stmt->execute();
if($stmt->fetch()) {
$stmt->close();
return true;
}
}
}
}
?>
I receive this warning error:
Warning: require_once(classes/settings.php): failed to open stream: No such file or
directory in /var/www/classes/Mysql.php on line 3 Fatal error: require_once(): Failed
opening required 'classes/settings.php' (include_path='.:/usr/share/php:/usr/share/pear')
in /var/www/classes/Mysql.php on line 3
I can't understand why, the file setting.php is in that folder, so what is the problem?
EDIT:
if I do the same this with another file for example this:
<?php
require_once 'classes/settings.php';
$host = "localhost";
$user = "root";
$pass = "pass";
$databaseName = "membership";
$tableName = "users";
//--------------------------------------------------------------------------
// 1) Connect to mysql database
//--------------------------------------------------------------------------
$con = mysql_connect($host,$user,$pass);
$dbs = mysql_select_db($databaseName, $con);
//--------------------------------------------------------------------------
// 2) Query database for data
//--------------------------------------------------------------------------
$result = mysql_query("SELECT * FROM $tableName"); //query
$array = mysql_fetch_row($result); //fetch result
//--------------------------------------------------------------------------
// 3) echo result as json
//--------------------------------------------------------------------------
echo json_encode($array);
?>
In this way, it works without problem, I can't understand why the file and the path is right because in this second piece code all work.
Your script, var/www/classes/Mysql.php, is already in the classes directory. The file you're including is in the same directory. Remove the classes/ and use:
require_once 'settings.php';
Since you are with in the classes folder already you have two options
First option is to use a relative path
require_once 'settings.php';
Second option is to use an absolute path
require_once $_SERVER['DOCUMENT_ROOT'] . '/classes/settings.php'
Try to use $_SERVER['DOCUMENT_ROOT']
require_once ($_SERVER['DOCUMENT_ROOT'] . '/classes/settings.php');
I'm in a bit of a pickle with freshening up my PHP a bit, it's been about 3 years since I last coded in PHP. Any insights are welcomed! I'll give you as much information as I possibly can to resolve this error so here goes!
Files
config.php
database.php
news.php
BLnews.php
index.php
Includes
config.php -> news.php
database.php -> news.php
news.php -> BLnews.php
BLnews.php -> index.php
Now the problem with my current code is that the database connection is being made but my database refuses to be selected. The query I have should work but due to my database not getting selected it's kind of annoying to get any data exchange going!
config.php
<?php
$dbhost = "localhost";
$dbuser = "root";
$dbpass = "";
$dbname = "test";
?>
database.php
<?php
class Database {
//-------------------------------------------
// Connects to the database
//-------------------------------------------
function connect() {
if (isset($dbhost) && isset($dbuser) && isset($dbpass) && isset($dbname)) {
$con = mysql_connect($dbhost, $dbuser, $dbpass) or die("Could not connect: " . mysql_error());
$selected_db = mysql_select_db($dbname, $con) or die("Could not select test DB");
}
}// end function connect
} // end class Database
?>
News.php
<?php
// include the config file and database class
include 'config.php';
include 'database.php';
...
?>
BLnews.php
<?php
// include the news class
include 'news.php';
// create an instance of the Database class and call it $db
$db = new Database;
$db -> connect();
class BLnews {
function getNews() {
$sql = "SELECT * FROM news";
if (isset($sql)) {
$result = mysql_query($sql) or die("Could not execute query. Reason: " .mysql_error());
}
return $result;
}
?>
index.php
<?php
...
include 'includes/BLnews.php';
$blNews = new BLnews();
$news = $blNews->getNews();
?>
...
<?php
while($row = mysql_fetch_array($news))
{
echo '<div class="post">';
echo '<h2> ' . $row["title"] .'</h2>';
echo '<p class="post-info">Posted by | <span class="date"> Posted on ' . $row["date"] . '</span></p>';
echo $row["content"];
echo '</div>';
}
?>
Well this is pretty much everything that should get the information going however due to the mysql_error in $result = mysql_query($sql) or die("Could not execute query. Reason: " .mysql_error()); I can see the error and it says:
Could not execute query. Reason: No database selected
I honestly have no idea why it would not work and I've been fiddling with it for quite some time now. Help is most welcomed and I thank you in advance!
Greets
Lemon
The values you use in your functions aren't set with a value. You likely need to convert the variables used to $this->dbName etc or otherwise assign values to the variables used.
Edit for users comment about variables defined in config.php:
You really should attempt to get the data appropriate for each class inside that class. Ultimately your variables are available to your entire app, there's no telling at this point if the variable was changed by a file including config.php but before database.php is called.
I would use a debugging tool and verify the values of the variables or just var_dump() them before the call.
Your Database class methods connect and selectDb try to read from variables that are not set ($dbhost, $dbname, $con, etc). You probably want to pass those values to a constructor and set them as class properties. Better yet, look into PDO (or an ORM) and forget creating your own db class.