This question already has an answer here:
Using MySQLi from another class in PHP
(1 answer)
Closed last year.
Now I want to finally move on and use classes. But I can't figure out a proper way to have access to mysql in functions of my classes without inclusion of the so called db.php file on top of each file.
db.php
class ConnectionDB{
private $server = "localhost";
private $username = "root";
private $password = "";
private $db = "oop_crud";
private $conn;
public function __construct(){
try{
$this->conn = new mysqli($this->server, $this->username,$this->password,$this->db);
}
catch (Exception $e){
echo "Connection faild" .$e->getMessage();
}
}
}
Usermodel.php
include 'db.php';
$ConnectionDB = new ConnectionDB();
class usermodel {
public function insert()
{
if (isset($_POST['submit'])) {
$name = $_POST['name'];
$mobile = $_POST['mobile'];
$email = $_POST['email'];
$password = $_POST['password'];
if ((!empty($name)) && (!empty($email)) && (!empty($mobile)) && (!empty($password))) {
$data = "INSERT INTO `register` (`u_id` , `name`, `mobile`,`email`,`password`) VALUES (NULL , '$name', '$mobile' , '$email', '$password')";
if ($sql = $this->conn->query($data)) {
echo "Yes";
}else{
echo "No";
}
}else{
echo '<div class="alert alert-danger alert-dismissible fade show"><button type="button" class="close" data-dismiss="alert">×</button><strong>Danger!</strong> All Field are Required </div>';
}
}
}
}
?>
i want to call ConnectionDB class in my usermodel file
What you should do is to think about an implementation of psr-4 autoloading. Please read more about this here: PSR-4
The easiest way to autoload classes is to use composer and composer init command in your project: Composer Installation
Once you run this command it will guide you through a few steps. Please choose "project" as a type and follow the instructions.
Then include autoload.php file from vendor/autoload.php in your index.php file and voila - if you follow psr-4 rules then all the classes will be loaded automatically without a need to use include 'db.php'; or similar code.
Related
I'm creating a CMS that provides dynamic database creation at the initial project setup stage.
I have defined the database configuration details as constants in config.php file:
//Database Name
define('DEFAULT_DB_NAME', 'cms');
//User Name
define('DEFAULT_USER_NAME', 'root');
//Password
define('DEFAULT_PASSWORD', '');
//Host Name
define('DEFAULT_HOST_NAME', 'localhost');
I included the config.php file in my database connection file (db.class.php):
<?php
include_once '../../config/config.php';
class Db{
protected $conn;
protected $host = DEFAULT_HOST_NAME;
protected $username = DEFAULT_USER_NAME;
protected $password = DEFAULT_PASSWORD;
protected $dbname = DEFAULT_DB_NAME;
public function __construct(){
$this->conn = new mysqli($this->host, $this->username, $this->password, $this->dbname);
if($this->conn->connect_error){
die("<h3>Connection Failed!!! Error: " . $this->conn->connect_error . "</h3>");
}
}
}
I also have created a dynamic Style sheet (admintheme.php) that modifies the admin panel based on user preference:
<?php
header("Content-type: text/css;");
include_once '../../model/admintheme.class.php';
$theme = new Admintheme();
$result = $theme->ReadAdminTheme();
if($result == '' || $result == '0'){
$sidebarBg = "#111";
$sidebarPosition = "left";
$sidebarunset = "left";
$sidebarright = "unset";
}
else{
$row = $result->fetch_assoc();
$sidebarBg = $row['sidebarbg'];
$sidebarPosition = $row['sidebar_position'];
if($sidebarPosition == "left"){
$sidebarunset = "right";
}
else{
$sidebarunset = "left";
}
}
?>
/*-- ------------------------xx----------------------- */
/***** Content Section Starts *****/
.content{
margin-<?= $sidebarPosition; ?>: auto;
}
/***** Content Section Ends *****/
/**** Side Bar Section Starts *****/
.sidebar-nav{
background-color: <?= $sidebarBg; ?>;
<?= $sidebarPosition; ?>: 0px;
}
The issue is that when I use static data in "db.class.php" file (ex. directly write "localhost" in place of the constant and so on..) then "admintheme.php" works fine and displays the desired output, but when I use constants in place of the static data then all other functionalities of the project work fine and retrieve data from the database except "admintheme.php".
The "admintheme.php" also works fine when the constants are defined inside the "db.class.php" or if the "config.php" file is in the same directory as of the "db.class.php" but while including the the "config.php" file from other directory, all other data is retrieved except "admintheme.php".
**No direct error is received but in the browser's console, it states (include_once(../../config/config.php): failed to open stream: No such file or directory...)
**Included path is correct in both "db.class.php" and "admintheme.php".
Any help is greatly appreciated.
Adding "DIR" magic constant solved the issue.
I'm developing Telegram Bot in PHP. At All of my projects i need check user register status and if not registered, store user info. for each project i wrote this step again and again.
Is there any ways to write a user class that usable ( whit some bit change ) in other projects and avoid this repeat?
This is my code.
// File: index.php
$user = User::isRegistered($this->telegram->UserID());
if ($user === false) {
$this->user = User::register($this->telegram);
} else
$this->user = $user;
And this my User class
// File: User.php
class User
{
public static function isRegistered($telegram_id)
{
$user = SlmUsers::find()->where(['telegram_id' => $telegram_id])->one();
if ($user)
return $user;
return FALSE;
}
public static function register(\Telegram $telegram)
{
$nickname = $telegram->FirstName() . ' ' . $telegram->LastName();
$nickname = mb_substr($nickname,0,128);
$user = new SlmUsers();
$user->telegram_id = $telegram->UserID();
$user->nickname = $nickname;
$user->telegram_username = $telegram->Username();
$user->message_id = 0;
$user->updated_at = date('U');
$user->last_request = 'new';
$user->save();
return $user;
}
}
but users table filed are different in each project so for store new user in other projects i should change all field of User::register. how i can avoid this? i want write a class do this works whit the lowest change in the origin class (User.php).
create one class file and define the function which you are going to use repeatedly in this classs file.
Import this file in the file where you want to use this function and call that function using the object of this class file
I have a strange bug at the moment in my web service I am coding.
When I am loading an specific url I get a success and error at the same time?
This is what I have in my index.php:
<?php
require_once 'functions/lib.php';
require_once 'core/init.php';
// Ask for request URL that was submitted and define scriptPath. Explode content of REQUEST URL to evaluate validity.
$requestURL = (($_SERVER['REQUEST_URI'] != "") ? $_SERVER['REQUEST_URI'] : $_SERVER['REDIRECT_URL']);
$scriptPath = dirname($_SERVER['PHP_SELF']);
$requestURL = str_replace($scriptPath, "", $requestURL);
$requestParts = explode("/", $requestURL);
// Check for valid api version
$validAPIVersions = array("v1");
$apiVersion = $requestParts[1];
// If API Version not in valid API array return 404, else OK.
if (!in_array($apiVersion, $validAPIVersions)) {
httpResponseCode(404);
echo $GLOBALS['http_response_code'];
echo "<br>" . "API Version not valid";
exit();
}
// Check for valid API endpoint
$validEndPoints = array("tickets");
$endPoint = $requestParts[2];
if (!in_array($endPoint, $validEndPoints)) {
httpResponseCode(404);
echo $GLOBALS['http_response_code'];
echo "<br>" . "Endpoint not valid";
exit();
}
// get the endpoint class name
$endPoint = ucfirst(strtolower($endPoint));
$classFilePath = "$apiVersion/$endPoint.php";
if (!file_exists($classFilePath)) {
httpResponseCode(404);
echo $GLOBALS['http_response_code'];
exit();
}
// load endpoint class and make an instance
try {
require_once($classFilePath);
$instance = new $endPoint($requestParts);
} catch (Exception $e) {
httpResponseCode(500);
echo $GLOBALS['http_response_code'];
exit();
}
and this is the corresponding "Tickets.php"
<?php
echo "OK";
?>
In the last two rows of my index.php, I am loading the specific class (named in the URL). For testing purposes, I have an "echo "OK" in this file. And this is the result when I am loading the URL I need:
http://api.medifaktor.de/v1/tickets
OK
Fatal error: Class 'Tickets' not found in /usr/www/users/kontug/api.medifaktor.de/webservice/index.php on line 45
I get the OK I was expecting AND the error for the Class Tickets, that is not found. Line 45 is
$instance = new $endPoint($requestParts);
Can someone give me a helping hand?
Best
Sebastian
The problem is that you don't have a class "Tickets" defined. After you load the tickets.php file, you are attempting to instantiate a class. Loading a file is not the same thing as defining a class. Within tickets.php (or some other included file), you need to define the class, like so:
class Tickets
{
// some properties here
private $endpoint;
// some methods here
public function __construct($endpoint)
{
$this->endpoint = $endpoint;
}
}
If you're not sure how to construct classes in PHP, read the section in the manual on classes.
Update: I added some example code within the class for version PHP5+.
Try the following for your test, in the 'ticket.php' file add:
class Ticket {
public function __construct()
{
echo 'testing';
}
}
Then make sure you either namespace or require the file.
I will be straight to the point with this. Can't seem to find it anywhere on the internet. Maybe it is not even possible, i dont know. I do really like to use the method "divide and rule", created it myself. Splitting as much files as possible for easy management (small files and such).
But here is my problem:
I have 5 files:
index.php
inc/config.php
inc/Database.class.php
inc/sidebar.php
inc/forms.php
Okay, what i have done is this:
in my config.php file i included the Database.class.php file and created an object.
include 'Database.class.php';
$user = "root";
$pass = "";
$host = "localhost";
$database = "blah blah";
$db = new Database($user, $pass, $host, $database);
$db->connect();
So i included this config.php and sidebar.php in my index.php file.
(shortened the code, but it functions the same)
include 'inc/config.php';
include 'inc/sidebar.php';
In my sidebar i have a form, for users to login.
in sidebar.php i just include forms.php, this is the forms.php:
(I used print_r to debug my file, to see if anything returns and i left out the method loginFormShow because it is very long and not relevant)
function loginFormProcess($user, $pass)
{
$db->select(blah blah some variables);
$res = $db->getResult();
print_r($res);
}
if (!isset($_POST['submit'])) {
loginFormShow();
} else {
if ($_POST['user'] == "")
{
loginFormShow(1);
}
else if ($_POST['pass'] == "")
{
loginFormShow(2);
}
else
{
$user = $_POST['user'];
$pass = $_POST['pass'];
loginFormProcess($user, $pass);
}
}
And thus, what the problem is. When i try to call the function loginFormProcess, it cant use the object $db.
Can i use 1 object for this? Because on the index page i am going to require some other data from the database. Do i need to create an object for the index page and one for the login form?
Is there any other solution?
If i am not clear, i would love to give some more explanation.
Cheers,
Clemenz
The best solution would be to pass the database object to the function's arguments as follows:
function loginFormProcess($user, $pass, Database $db) {
And call it with an appropriate Database object. This is what know as dependency-injection.
Try this:
function loginFormProcess($user, $pass)
{
global $db;
$db->select(blah blah some variables);
$res = $db->getResult();
print_r($res);
}
For reference: http://php.net/manual/en/language.variables.scope.php
You need to declare $db as global.
Try this:
function loginFormProcess($user, $pass)
{
global $db;
$db->select(blah blah some variables);
$res = $db->getResult();
print_r($res);
}
See: http://www.php.net/manual/en/language.variables.scope.php
The variable $db is created as a global variable in your config.php file. This is invisible from inside the loginFormProcess function. A shotcut solution you can use is declaring your intention of using a global variable by adding the statement global $db; as the first statement inside your function
In the code given below, I am trying to modify it in such a way that the db connection variables are used from a config file. This should make the password more secure as I can restrict the config file's permissions.
Kindly let me know if there is a way by which I can modify the code to get the db variables from another file/config file?
class ActivitycodesCollection {
var $list, $err, $sql;
// --- Private variables for database access
var $_db_host = "######";
var $_db_username = "######";
var $_db_passwd = "######";
var $_db_name = "######";
function query ($where="") {
mysql_pconnect ($this->_db_host, $this->_db_username, $this->_db_passwd);
mysql_select_db ($this->_db_name);
$where = "WHERE " . $where;
$sql = "SELECT * FROM activitycodes $where";
$result = mysql_query ($sql);
$this->err = mysql_error();
$this->sql = $sql;
if (mysql_num_rows($result) > 0) {
while (list($id) = mysql_fetch_array ($result)) {
$this->list[$id] = new activitycodes($id);
}
}
}
}
I tried including the config.ini file in this class/function but it threw an error like
unexpected T_VARIABLE, expecting T_FUNCTION
Your code is hopelessly outdated.
1) Don't use var for properties, use private or protected.
2) Don't use mysql_* functions, use PDO.
3) Don't keep connection details inside the class. Just require PDO connection in constructor.
4) Don't trust any data outside your scope - don't allow just write some untrusted text into your SQL query (you do it by $where variable).
5) Read books. "PHP Objects, Patterns, and Practice" will help you now, and "Clean code" - little bit later.
Example:
class ActivitycodesCollection
{
private $list;
private $PDO;
private $table_name;
public function __construct(\PDO $PDO, $table_name)
{
$this->PDO = $PDO;
$this->table_name = $table_name;
}
public function fetchByParameter($parameter)
{
$query = $this->PDO->prepare("SELECT `id` FROM `{$this->table_name}` WHERE "
." some_field = :parameter");
if (!$query)
{
return false;
}
if (!($query->execute(array(':parameter'=> $parameter))))
{
return false;
}
$results = $query->fetchAll(\PDO::FETCH_ASSOC);
if (!empty($result))
{
foreach ($results as $result)
{
$id = $result['id'];
$this->list[$id] = new ActivityCodes($id);
}
}
}
}
Without seeing the "config" file it's not possible to say how to write a parser for it. A simple solution would be to write some php code which sets the variables - but if you include / require it, the variables will be set in global scope - not within the method. But you could eval(file_get_contents($config_file_path)) - which would set the variables in local scope at the risk of providing a method for code injection.
BTW there are a large number of issues with the code you have provided. Leaving aside the potential risk of SQL injection, if the method parameter is null / blank, then the query will be malformed (consider function query ($where="1"). Relying on specific column ordering is bad practice.
It's also hard to imagine how yo restrict access to this config file when the only practical means would be via suphp or base opendir.
Putting the SQL connection data in a separate files does not increase security at all. Actually, storing them in a file that does not have a .php extension makes it less secure since it might be accessible by a user while the code of a PHP file is not visible to any users. You also cannot use more restrictive permissions on the config file than on your PHP files since whatever user PHP is running as (usually the webserver user) needs to access them.
Simply store the connection data in a PHP file:
<?php
define('DB_HOST', '...');
define('DB_NAME', '...');
define('DB_USER', '...');
define('DB_PASS', '...');
Then include this file (outside your class definition) and use the constants when making the connection.
You can use parse_ini_file in you constructor.
class ActivitycodesCollection {
var $list, $err, $sql;
const CONFIG_FILE = 'config.ini';
// --- Private variables for database access
var $_db_host = ''
var $_db_username = '';
var $_db_passwd = '';
var $_db_name = '';
public function ActivitycodesCollection() {
$config = parse_ini_file(self::CONFIG_FILE);
$this->_db_host = $config['db']['host'];
//etc
}
public function query ($where="") {
mysql_pconnect ($this->_db_host, $this->_db_username, $this->_db_passwd);
mysql_select_db ($this->_db_name);
$where = "WHERE " . $where;
$sql = "SELECT * FROM activitycodes $where";
$result = mysql_query ($sql);
$this->err = mysql_error();
$this->sql = $sql;
if (mysql_num_rows($result) > 0) {
while (list($id) = mysql_fetch_array ($result)) {
$this->list[$id] = new activitycodes($id);
}
}
}
And the ini file should be something like that :
[db]
host = localhost
name = foo
user = bar
pass = baz