How can I complete my dropdown with database data? - php

I'm building an application based on Slim Framework, and I already have some working code. To return a JSON response with a list of projects, I wrote the following:
Controller class (controllerProyectos.php)
<?php
require "transferController/transferProyectos.php";
class NombreProyecto {
public function getProyectos() {
$list = array();
foreach ($this->fillObject() as $sKey => $oValue) {
$list[] = array(
'id' => $oValue->getId(),
'nombre_proyecto' => $oValue->getNombre(),
'state' => $oValue->getState(),
);
}
return $list;
}
private function fillObject() {
$aObjects = array();
for ($i = 0; $i < 5; $i++) {
$oTransfer = new TransferProyeCtr();
$oTransfer->setId($i);
$oTransfer->setNombre("proyecto " . $i);
$oTransfer->setState(1);
$aObjects[] = $oTransfer;
}
return $aObjects;
}
}
Front controller (index.php)
<?php
require "vendor/autoload.php";
$sPathApi = "/api/sistemaTareas/";
$app = new \Slim\Slim();
$app->get($sPathApi . $sVersion . 'proyectos', function () {
require "controller/controllerProyectos.php";
$oProyecto = new NombreProyecto();
header('Content-Type: application/json');
echo json_encode($oProyecto->getProyectos());
exit();
});
Model class (transferProyectos.php)
<?php
class TransferProyeCtr {
private $sNombre;
private $iId;
private $iState;
public function getNombre() {
return $this->sNombre;
}
public function setNombre($nombre) {
$this->sNombre = $nombre;
}
public function getId() {
return $this->iId;
}
public function setId($Id) {
$this->iId = $Id;
}
public function getState() {
return $this->iState;
}
public function setState($state) {
$this->iState = $state;
}
}
As you can see I'm using some mockup data in the controller. When I do an AJAX request to my application, I get the following result in a dropdown:
- proyecto 1
- proyecto 2
- proyecto 3
- proyecto 4
- proyecto 5
So far everything is working as expected. But I'd like to return real data from the database in that controller.
I wrote a function (inside bdconnection.php file) to open the database connection:
<?php
function connect_db() {
$server = 'localhost';
$user = 'root';
$pass = '123asd';
$database = 'bd_actividades';
$connection = new mysqli($server, $user, $pass, $database);
return $connection;
}
I think that in my controller I need something like:
public function getPro() {
require "sistema/bdconnection.php";
$sql = "select pro_nombre FROM act_proyecto";
try {
$db = connect_db();
$stmt = $db->query($sql);
$users = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
echo json_encode($users);
} catch(PDOException $e) {
echo json_encode($e->getMessage());
}
}
And replace $oTransfer->setNombre("proyecto " . $i); for $oTransfer->setNombre($users);, but I'm not sure.
Just to give you guys a little more detail about my application, here will go the files structure and database data:

Related

Creating a Cursor Based Pagination System in PHP

I am trying to figure out how how to create my own simple cursor based pagination system in PHP and am having difficulty trying to understand how star starting_after and starting_before works as mentioned in this medium.com post for how the company stripe deals with cursor pagination. In my case I am using the id column that is in ascending order to hopefully make this work. The issue that I am having is getting an id for the first "page". Currently my first page would direct to the second page since starting_after leads to the next page and not the currently page. Any advice for how to build this out would be awesome. I already created page based pagination, but think that cursor pagination would be more useful for most of my cases.
I have attached the two files that I have created thus far to try to get this to work.
Pagination class
<?php
require_once "DB.php";
class New_Pagination {
private $table = "";
private $limit;
private $starting_after = "";
private $starting_before = "";
private $db;
public function __construct() {
$this->db = DB::getInstance();
}
public function getLimit(): int {
return $this->limit;
}
public function setLimit(int $limit): void {
$this->limit = $limit;
}
public function getStartingAfter(): string {
return $this->starting_after;
}
public function setStartingAfter(string $starting_after): void {
$this->starting_after = $starting_after;
}
public function getStartingBefore(): string {
return $this->starting_before;
}
public function setStartingBefore(string $starting_before): void {
$this->starting_before = $starting_before;
}
public function getTable(): string {
return $this->table;
}
public function setTable(string $table): void {
$this->table = $table;
}
public function idExists($id) {
$result = $this->db->find(self::getTable(), [
"select" => "id",
"conditions" => "id = $id",
"fetchType" => "single"
]);
if (empty($result)) {
return FALSE;
} else {
return $result->id;
}
}
public function getData($starting_after, $starting_before) {
self::setStartingAfter($starting_after);
self::setStartingBefore($starting_before);
$starting_after = self::getStartingAfter();
$starting_before = self::getStartingBefore();
$data = [];
$order = !empty($starting_after) ? "ASC" : "DESC";
if (empty($starting_after) && empty($starting_before)) {
$data["data"] = $this->db->find(self::getTable(), [
"select" => "*",
"order" => "id ASC",
"limit" => self::getLimit(),
"fetchType" => "all"
]);
} else {
$data["data"] = $this->db->find("carousel_image", [
"select" => "*",
"conditions" => "id >= '$starting_after' OR id <= '$starting_before'",
"order" => "id $order",
"limit" => self::getLimit(),
"fetchType" => "all"
]);
}
$next = self::idExists($data["data"][count($data["data"]) - 1]->id + 1);
$previous = self::idExists($data["data"][0]->id - 1);
$data["cursor"] = [
"next" => $next,
"previous" => $previous
];
return $data;
}
public function generateLink() {
$test = self::getData("", "");
$test2 = [];
$test2[0] = $test;
$i = 0;
do {
$test2[$i] = $test;
$test = self::getData($test["cursor"]["next"], "");
$i++;
$test2[$i] = $test;
} while ($test["cursor"]["next"] !== FALSE);
$test2[$i] = $test;
echo "<ul>";
$j = 1;
foreach ($test2 as $key => $val) {
if ($val["cursor"]["next"] !== FALSE) {
$url = "/process.php?starting_after=" . $val["cursor"]["next"];
echo "<li>";
echo "<a href='$url'>$j</a>";
echo "</li>";
$j++;
}
}
echo "<ul>";
}
}
Test file
$pagination = new New_Pagination();
$pagination->setLimit(2);
$pagination->setTable("carousel_image");
echo "<pre>";
$pagination->generateLink();
echo "</pre>";
The cursors are useful to prevent scan big tables and allow to move in very big sources (files, external resources, etc., etc.). In the majority of the cases, cursors are provided by binary libraries and supported by the core of the related system (mysql, files). If you try to emulate this behavior in not natural way you must take care because you could add overhead and get unexpected results.
In the other hand, is very useful to have a pagination class, but be aware, this class have some problems.
getData is very expensive because it performs 3 queries to get a batch of results
the class is too verbose, the getters and setters add too much noise
the results are sorted using very rare criteria. Remember, if you are in search results you need the same order moving to the next page and moving to the previous page
My suggestions...
Create interfaces
<?php
interface CursorAble {
public function fetchNext ($startingAfter);
public function fetchPrev ($startingBefore);
public function getPreviousLink ();
public function getNextLink ();
}
interface Pageable {
public function getCollectionSize ();
public function getPageSize ();
public function getPagesCount ();
public function getPageLinks ();
}
When you create interfaces you ensures that the classes expose the desired behavior and furthermore delegate the specialized details to the concrete implementations. The concrete implementations can define it dependencies in the constructor, something very good when you relies on dependency injection.
CursorAble implementation example
<?php
class PdoCursorAbleTable implements CursorAble {
private $pdo;
private $table;
private $results;
private $pageSize;
public function __construct (PDO $pdo, $table, $pageSize = 100) {
$this->pdo = $pdo;
$this->table = $table;
$this->pageSize = (int)$pageSize ?: 100;
}
public function fetchNext ($startingAfter) {
$s = $this->pdo->prepare("select * from {$this->table} where id > :starting_after limit {$this->pageSize}");
$s->bindValue(':starting_after', $startingAfter, PDO::PARAM_INT);
$s->execute();
$this->results = $s->fetchAll() ?: [];
return $this->results;
}
public function fetchPrev ($startingBefore) {
$s = $this->pdo->prepare("select * from {$this->table} where id < :starting_before limit {$this->pageSize}");
$s->bindValue(':starting_before', $startingBefore, PDO::PARAM_INT);
$s->execute();
$this->results = $s->fetchAll() ?: [];
return $this->results;
}
public function getPreviousLink () {
return !$this->results ? '' : '?starting_before=' . $this->results[0]->id;
}
public function getNextLink () {
if (!$this->results || count($this->results) < $this->pageSize) return '';
return '?starting_after=' . $this->results[count($this->results)]->id;
}
}
And the Pageable example
<?php
class PdoPageableTable implements Pageable {
private $pdo;
private $table;
private $pageSize;
private $collectionSize;
public function __construct (PDO $pdo, $table, $pageSize = 100) {
$this->pdo = $pdo;
$this->table = $table;
$this->pageSize = $pageSize;
}
public function getCollectionSize () {
if ($this->collectionSize === null) {
$s = $this->pdo->prepare("select count(id) from {$this->table}");
$s->execute();
$this->collectionSize = $s->fetchColumn('0');
}
return $this->collectionSize;
}
public function getPageSize () {
return $this->pageSize;
}
public function getPagesCount () {
return ceil($this->collectionSize / $this->getPageSize());
}
public function getPageLinks () {
$pages = [];
foreach (range(1, $this->getPagesCount()) as $page) {
$pages[] = '?page=' . $page;
}
return $pages;
}
}
The test file
<?php
$pagination = new PdoCursorAbleTable($pdo, 'carousel_image', 2);
echo "<pre>";
$startingAfter = 0;
$results = $pagination->fetchNext($startingAfter);
foreach ($results as $result) {
// do something
}
echo $pagination->getNextLink();
echo "</pre>";

PHP api rest router issue

To test my android application in a more concrete way, and since my company has no API yet, I decided to "create" it in a simplified way for testing purpose (and learning, i'm only an intern).
The Android app uses Retrofit.
Anyway, I followed one tutorial for a "login" method, where I use the "Post" method in android, passing login and password as #field datas, and everything worked fine, I could retrieve the data in my android app and log in (I do not manage security yet, this will be added later when they hire a devOp)
The problem is after that I wanted to create a Router for more complicated urls (like "/model/client/:id/contracts") and now nothing work anymore. I do not use framework, only composer. I end my internship in two days I do not really have time to learn a big thing.
So, here are the classes that were working before I make the router :
/src/Model/client/login.php :
<?php
namespace App\Model\client;
// required headers
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: access');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Credentials: true');
header('Content-Type: application/json');
// include database and object files
include_once 'src/config/Database.php';
include_once 'src/Model/client/client.php';
// Instantiate database and connect
$database = new Database();
$db = $database->connect();
// prepare product object
$client = new Client($db);
console.log("Login launched");
// set ID property of record to read
$client->login = isset($_POST['login']) ? $_POST['login'] : die();
$client->password = isset($_POST['password']) ? $_POST['password'] : die();
// read the details of product to be edited
$result = $client->readOne();
$num = $result->rowCount();
//Check if corresponding client
if($num>0){
if($client->city==3){
$client->city = "Valenciennes";
}
$row = $result->fetch(PDO::FETCH_ASSOC);
if($row['city']==3){
$city = "Valenciennes";
} else {$city='randomname';}
$client->id = $row['id'];
$client->login = $row['login'];
$client->raison = $row['raison'];
$client->addr1 = $row['addr1'];
$client->addr2 = $row['addr2'];
$client->city = $city;
$client->telephone = $row['telephone'];
$client->portable = $row['portable'];
$client->fax = $row['fax'];
$client->email = $row['email'];
$client->tva_intra = $row['tva_intra'];
$client->siret = $row['siret'];
$client->gtr = $row['gtr'];
$client->password = $row['password'];
// create array
$logged_client = array(
'id' => $client->id,
'login'=> $client->login,
'raison' => $client->raison,
'addr1' => $client->addr1,
'addr2' => $client->addr2,
'city' => $client->city,
'telephone'=>$client->telephone,
'portable'=>$client->portable,
'fax'=>$client->fax,
'email'=>$client->email,
'tva_intra'=>$client->tva_intra,
'siret'=>$client->siret,
'password'=>$client->password);
// set response code - 200 OK
http_response_code(200);
// make it json format
echo json_encode($logged_client);
}
else {
// set response code - 404 Not found
http_response_code(404);
// tell the user product does not exist
echo json_encode(array("message" => "Client does not exist.".$client->login));
}
?>
The class of the object I need to retrieve (src/Model/client/client):
<?php
class Client{
//db stuff
private $cnx;
private $table_name='client';
//client properties
public $id;
public $login;
public $nom;
public $raison;
public $addr1;
public $addr2;
public $city;
public $telephone;
public $portable;
public $fax;
public $email;
public $tva_intra;
public $siret;
public $gtr;
public $password;
//constructor
public function __construct($db){
$this->cnx = $db;
}
//GetOne ###########################################################################
function readOne(){
$query = 'SELECT * FROM '.$this->table_name.' WHERE login = ? AND password = ?';
// prepare query statement
$stmt = $this->cnx->prepare($query);
// bind id of product to be updated
$stmt->bindParam(1, $this->login);
$stmt->bindParam(2, $this->password);
// execute query
$stmt->execute();
// get retrieved row
return $stmt;
}
}
?>
The database exists, here is the connection and it worked fine :
<?php
class Database {
//DB Params
private $host='localhost';
private $db_name='techcrea';
private $username = 'root';
private $pwd = '';
private $cnx;
//DB Connect
public function connect(){
$this->cnx = null;
try {
$this->cnx = new PDO('mysql:host='.$this->host.';dbname='. $this->db_name, $this->username,$this->pwd);
$this->cnx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
echo 'Connection Error:'.$e->getMessage();
}
return $this->cnx;
}
}
So here are the problems starting : this are the classes I added and now nothing works anymore, I get router exception errors (no matching routes) etc..., not only in my android app that returns an "onfailure" response, but also when i try the url in my navigator :
1 - Index :
<?php
require 'vendor/autoload.php';
$router= new App\Router\Router($_GET['url']);
$router->get('/', function(){
echo "homepage";
});
$router->post('/Model/client/login', function(){
//require_once 'src/Model/client/login.php';
});
$router->get('/Model/client/:id/contrats', function($id){
echo "contrats";
});
$router->run();
2 - Router
<?php
namespace App\Router;
class Router {
private $url;
private $routes =[];
private $namedRoutes= [];
public function __construct($url){
$this->url = $url;
}
public function get($path, $callable, $name =null){
return $this->add($path,$callable,$name,'GET');
}
public function post($path, $callable, $name=null){
return $this->add($path,$callable,$name,'POST');
}
public function patch($path, $callable, $name=null){
return $this->add($path,$callable,$name,'PATCH');
}
public function put($path, $callable, $name=null){
return $this->add($path,$callable,$name,'PUT');
}
public function delete($path, $callable, $name=null){
return $this->add($path,$callable,$name,'DELETE');
}
private function add($path, $callable,$name,$method){
$route = new Route($path, $callable);
$this->routes[$method][]= $route;
if($name){
$this->namedRoutes[$name] = $route;
}
return $route;
}
public function url($name,$params = []){
if(!isset($this->namedRoutes[$name])){
throw new RouterException("no match name route");
}
$this->namedRoutes[$name]->getUrl($params);
}
public function run(){
if(!isset($this->routes[$_SERVER['REQUEST_METHOD']])){
throw new RouterException('request method does not exist');
}
foreach($this->routes[$_SERVER['REQUEST_METHOD']] as $route){
if($route->match($this->url)){
return $route->call();
}
}
throw new RouterException('no matching routes');
}
}
3 - Route
namespace App\Router;
class Route {
private $path;
private $callable;
private $matches = [];
private $params = [];
public function __construct($path, $callable){
$this->path = trim($path,'/');
$this->callable = $callable;
}
public function with($param, $regex){
$this->params[$param] = str_replace('(','(?:', $regex);
return $this;
}
public function match($url){
$url=trim($url, '/');
$path = preg_replace_callback('#:([\w]+)#', [$this, 'paramMatch'], $this->path);
$regex = "#^$path$#i";
if(!preg_match($regex, $url, $matches)){
return false;
}
array_shift($matches);
$this->matches= $matches;
return true;
}
public function call(){
if(is_string($this->callable)){
$params = explode('#', $this->callable);
$controller = "App\\Controller\\".$params[0]."Controller";
$controller = new $controller();
$action = $params[1];
return $controller->$action();
} else {
return call_user_func_array($this->callable, $this->matches);
}}
private function paramMatch($match){
if(isset($this->params[$match[1]])){
return '('.$this->params[$match[1]].')';
}
return '([^/]+)';
}
public function getUrl($params){
$path = $this->path;
foreach($params as $k=>$v){
$path= str_replace(":$k",$v, $path);
}
return $path;
}
}
and the htaccess doc :
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
Thank you very much if you help me

Convert PHP 5.6 news script to 7.2

I have a PHP 5.6 compatible script. Now in my server i have to change to php7.2, but this script get error everywhere.I want to convert it myself but my knowledge does not reach much. I have been advancing little by little with several tutorials but I have already been stuck without being able to continue.
I need help to do it myself. This is just an example of the code, but by solving this, I think I will be able to convert the whole site.
The error:
[01-Nov-2018 09:16:58 UTC] PHP Fatal error: Uncaught Error: Call to a member function query() on null in /home/xxxx/public_html/incs/generales/fullnews.php:433
Stack trace:
#0 /home/xxxx/public_html/news.php(16): FullNewsInc->getFullNews('18880', 'fullnews')
#1 {main}
thrown in /home/xxxx/public_html/incs/generales/fullnews.php on line 433
the news.php page
<?php
require_once './db.php'; $db = new DB_Sql(); $db2 = new DB_Sql();
include_once './fullnews.php';
$fullnewsinc = new FullNewsInc($db);
$newsId = $_REQUEST['newsId'];
$system = $_REQUEST['system'];
$cat = $_REQUEST['categorie'];
?>
<section id="main-content" itemscope itemtype="https://schema.org/Article">
<div id="latest">
<section class="noticias">
<div class="clearfix"></div>
<?php $fullnewsinc->getFullNews($newsId, 'fullnews'); ?>
</section>
<aside class="sidebar">
</aside>
</div> <!-- END Latest -->
<div class="clearfix"></div>
</section>
This is the function in fullnews.php
<?php
class FullNewsInc {
var $db;
public function __construct()
{
// Constructor's functionality here, if you have any.
}
public function FullNewsInc(&$db) {
$this->db = &$db; self::__construct();
}
function getFullNews($newsId = '', $template = 'theme_fullnews') {
$sql = "SELECT x FROM";
$this->db->query($sql);
while($this->db->next_record()) {
$newsId = $this->db->f("newsId");
$subject = $this->db->f("subject");
$shortNews = $this->db->f("shortNews");
$longNews = $this->db->f("longNews");
$iconId = $this->db->f("iconId");
$source = $this->db->f("source");
include "./theme/".$template.".tpl.php";
}
}
}?>
This is the db.php
<?php
if (!class_exists('DB_Sql')){
class DB_Sql {
public function __construct()
{
// Constructor's public functionality here, if you have any.
}
public $Host = "xxx";
public $Database = "xxxx";
public $User = "xxx";
public $Password = "xxxxx";
public $Auto_Free = 1;
public $Debug = 0;
public $Halt_On_Error = "no"; // "yes", "no", "report"
public $Record = array();
public $Row;
public $Errno = 0;
public $Error = "";
public $Link_ID = 0;
public $Query_ID = 0;
public function DB_Sql($query = "") {
$this->query($query);self::__construct();
}
public function link_id() {
return $this->Link_ID;self::__construct();
}
public function query_id() {
return $this->Query_ID;self::__construct();
}
public function connect($Database = "", $Host = "", $User = "", $Password = "") {
if ("" == $Database)
$Database = $this->Database;
if ("" == $Host)
$Host = $this->Host;
if ("" == $User)
$User = $this->User;
if ("" == $Password)
$Password = $this->Password;
if ( 0 == $this->Link_ID ) {
$this->Link_ID=#mysqli_connect($Host, $User, $Password, $Database);
if (!$this->Link_ID) {
$this->halt("connect failed - Please check your database settings.");
die;
}
if (!#mysqli_select_db($Database,$this->Link_ID)) {
$this->halt("cannot use database ".$this->Database." - Please check your database settings.");
die;
}
}
return $this->Link_ID;
}
public function free() {
#mysql_free_result($this->Query_ID);
$this->Query_ID = 0;self::__construct();
}
public function query($Query_String) {
if ($Query_String == "") {
return 0;
}
if (!$this->connect()) {
return 0;
}
# New query, discard previous result.
if ($this->Query_ID) {
$this->free();
}
if ($this->Debug)
printf("Debug: query = %s<br />\n", $Query_String);
$this->Query_ID = #mysqli_connect($Query_String,$this->Link_ID);
$this->Row = 0;
$this->Errno = mysql_errno();
$this->Error = mysql_error();
if (!$this->Query_ID) {
$this->halt("Invalid SQL: ".$Query_String);
}
return $this->Query_ID;self::__construct();
}
public function next_record() {
if (!$this->Query_ID) {
$this->halt("next_record called with no query pending.");
return 0;
}
$this->Record = #mysqli_fetch_array($this->Query_ID);
$this->Row += 1;
$this->Errno = mysql_errno();
$this->Error = mysql_error();
$stat = is_array($this->Record);
if (!$stat && $this->Auto_Free) {
$this->free();
}
return $stat;self::__construct();
}
public function affected_rows() {
return #mysql_affected_rows($this->Link_ID);self::__construct();
}
public function num_rows() {
return #mysql_num_rows($this->Query_ID);self::__construct();
}
public function num_fields() {
return #mysql_num_fields($this->Query_ID);self::__construct();
}
public function nf() {
return $this->num_rows();self::__construct();
}
public function np() {
print $this->num_rows();self::__construct();
}
public function f($Name) {
return $this->Record[$Name];self::__construct();
}
public function p($Name) {
print $this->Record[$Name];self::__construct();
}
public function halt($msg) {
$this->Error = #mysqli_error($this->Link_ID);
$this->Errno = #mysqli_errno($this->Link_ID);
if ($this->Halt_On_Error == "no")
return;
$this->haltmsg($msg);
if ($this->Halt_On_Error != "report")
die("Session halted.");self::__construct();
}
public function haltmsg($msg) {
printf("<b>Database error:</b> %s<br />\n", $msg);
printf("<b>MySQL Error</b>: %s (%s)<br />\n",
$this->Errno,
$this->Error);self::__construct();
}
}
}
The theme_fullnews tamplate:
<article>
<header>
<h1 itemprop="name" ><?php echo $subject; ?></h1>
<h2 itemprop="articleSection"><?php echo $shortNews; ?></h2>
<span itemprop="datePublished" content=" <?php echo $newDate; ?>"> <?php echo time_elapsed_string($timestamp); ?> </span>
</div>
</header>
<section>
<?php $longNews); ?>
</section>
</article>
What's happening here is that you have functions inside your class with the same name as the class. PHP is warning you that the ability to do this is going to be removed in future.
For example, you have your php class
<?php
class FullNewsInc {
public function __construct( )
{
// Constructor's public functionality here, if you have any.
}
/**
Some code here
**/
public function FullNewsInc($db){
$this->db = &$db;
}
/**
More code here
**/
}
The class and method name match, so you would need to change your PHP class to use the __construct method, which you've written, but it is currently blank.
class FullNewsInc {
public function __construct( $db )
{
// Constructor's public functionality here, if you have any.
$this->db = &$db;
}
/**
Some code here
**/
//The FullNewsInc method has been deleted. The code contained within was moved to the __construct
/**
More code here
**/
}
There is more information available on the php.net site http://php.net/manual/en/language.oop5.decon.php

Class with a db query, extending, functions and views. Am I doing it right way?

I have just a little progress in practicing. Most of my code works but I am not sure if I do things the right way?
Please, can you tell me if I do mistakes and correct me.
First, I create autoload functions:
function autoload_models($model) {
if (file_exists(MODELS_PATH . $model . '.php')) {
require_once MODELS_PATH . $model . '.php';
return true;
} else {
return false;
}
}
spl_autoload_register('autoload_models');
function autoload_controllers($controller) {
if (file_exists(CONTROLLERS_PATH . $controller . '.php')) {
require_once CONTROLLERS_PATH . $controller . '.php';
return true;
} else {
return false;
}
}
spl_autoload_register('autoload_controllers');
I have a class like this:
class Category {
public $db;
public $rows;
public $id;
public function build_category() {
global $db;
global $rows;
$db = new Database();
$db->query("SELECT * from categories");
$rows = $db->resultset();
}
public function category_items() {
global $db;
global $rows;
global $id;
$db = new Database();
$db->query("SELECT * from posts WHERE category_id = '$id'");
$rows = $db->resultset();
}
}
I extend with another class (still have some issues here. Nothing prints):
class Category_Items extends Category {
public $db;
public $rows;
public $id;
public function display_category_items() {
// Call the parent class function
parent::category_items();
global $rows;
global $id;
// Check if the page parameter is integer
if (ctype_digit($_GET['id'])) {
$id = $_GET['id'];
} else {
print "Illegal category page parameter";
}
foreach ($rows as $row) {
print "test";
print $row['post_title']; // This does not work yet. Nothing prints
}
}
}
Class for building a menu with categories (Everything works here):
class Categories_Menu extends Category {
public $db;
public $rows;
public function build_category_menu() {
parent::build_category();
global $rows;
foreach ($rows as $row) {
require VIEWS_PATH . 'categories/categories_menu.php';
}
}
}
And finally instances:
$category_menu = new Categories_Menu();
$category_menu->build_category_menu();
$category_items = new Category_Items();
$category_items->display_category_items();
Thank you for your time and help!
Where do the global variables come from?
Anyway, you should get rid of them.
I guess your rows var does not get changed, after any interaction. Using globals also will not be relevant in extending classes.
Your public properties and globals mentioned, does no interact each other. Thus, the object members seems to be totally useless.
What I would suggest in simple schems would be
class Model {
protected $_db;
public function __construct(Database $db) {
$this->_db = $db;
}
}
class Category extends Model {
public $_rows;
public $_id;
public function build_category() {
$this->_db->query("SELECT * from categories");
$this->_rows = $this->_db->resultset();
}
public function category_items() {
$this->_db->query("SELECT * from posts WHERE category_id = '{$this->_id}'");
$this->_rows = $this->_db->resultset(); // here you will overwrite $_rows ?
}
class Categories_Menu extends Category {
public $_rows;
public function build_category_menu() {
$this->build_category();
foreach ($this->_rows as $row) {
require VIEWS_PATH . 'categories/categories_menu.php';
}
}
}
class Category_Items extends Category {
public $_rows;
public $_id;
public function display_category_items() {
if (ctype_digit($_GET['id'])) { // just intval it, or use is_int?
$this->_id = $_GET['id'];
} else {
print "Illegal category page parameter";
}
// You assign value to $_id, then call the function that requires it
$this->category_items();
foreach ($this->_rows as $row) {
print "test";
print $row['post_title'];
}
}
}

How to print array?

I'm trying to learn how to print results from a query, but I'm getting confused.
Config Table:
site_id | site_name | site_description
1 Test Testing
Config:
private $hostname = 'localhost';
private $username = 'blah';
private $password = 'blah';
private $database = 'blah';
public function __construct()
{
$this->connection = new mysqli($this->hostname,$this->username,$this->password,$this->database);
if($this->connection->connect_errno)
{
die('Error: ' . $this->connection->error);
}
}
public function query($query)
{
return $this->connection->query($query);
}
public function __destruct()
{
$this->connection->close();
}
Code #1:
public function __construct()
{
$this->db = new Config;
$si = $this->db->query('SELECT * FROM config');
while($site_if = $si->fetch_array())
{
$this->site_info[] = $site_if;
}
}
public function getSiteName()
{
echo $this->site_info['site_name'];
}
This prints nothing.
Code #2:
public function __construct()
{
$this->db = new Config;
$si = $this->db->query('SELECT * FROM config');
while($site_if = $si->fetch_array())
{
$this->site_name_info = $site_if['site_name'];
}
}
public function getSiteName()
{
echo $this->site_name_info;
}
This prints the info, but is it the correct approach? Is there a way to print with Code #1?
All I want to do is echo site name. There is only one site name.
Without more info about your config table design the only think I can suggest is something like that:
while($site_if = $si->fetch_array())
{
$this->site_info[$site_if["NAME_COLUMN_NAME"]] = $site_if["VALUE_COLUMN_NAME"];
}
NAME_COLUMN_NAME and VALUE_COLUMN_NAME have to be replaced with column names from your table design.
After that you'll be able to get custom config parameter from $this->site_info array by it's name, eg.
public function getSiteName()
{
echo $this->site_info['site_name'];
}
In example #1, $this->site_info contains an array of arrays. To simply see the contents:
print_r($this->site_info);
To loop over the contents, printing the names of each row:
foreach ($this->site_info as $row){
echo $row['site_name'];
}

Categories