mysql_fetch_object with specific class - php

I developed an object-oriented guestbook and I have my Class GuestBookEntry:
class GuestBookEntry {
protected $id;
protected $entryDate;
protected $authorName;
protected $authorMail;
protected $entryText;
// getters, setters and specific functions are omitted
}
I also have a mysql table with the same names as columns.
Well, when I fetch guestbook entries, it seems to work, but it only displays the ID and the Date, which where returned by getters. The other things won't return to the template.
The code looks like this:
public function showEntries() {
$query = mysql_query('SELECT * FROM dng_entries ORDER BY id DESC');
while($entry = #mysql_fetch_object($query, 'GuestBookEntry')) {
if(empty($entry)) {
echo '<font color="white">Keine Einträge vorhanden...</font>';
} else {
var_dump($entry);
echo '<table class="table table-bordered entryfield" align="right">
<thead>
<tr>
<td rowspan="2">'.$entry->getId().'</td>
<td width="20%">Datum:</td>
<td>Name:</td>
<td>Email:</td>
</tr>
<tr>
<td>'.$entry->getEntryDate().'</td>
<td>'.$entry->getAuthorName().'</td>
<td>'.$entry->getAuthorMail().'</td>
</thead>
<tbody>
<tr>
<td width="10%" valign="middle">Eintrag:</td>
<th colspan="3" valign="top" height="100px">'.$entry->getEntryText().'</td>
</tr>
</tbody>
</table>';
}
}
}
Here's a var_dump of e.g. object:
object(GuestBookEntry)#2 (5) { ["id":protected]=> string(1) "2" ["entryDate":protected]=> int(1344696811) ["authorName":protected]=> NULL ["authorMail":protected]=> NULL ["entryText":protected]=> NULL }
update: well here is the rest of GuestBookEntry class:
public function __construct($authorName, $authorMail, $entryText) {
$this->authorName = $authorName;
$this->authorMail = $authorMail;
$this->entryDate = time();
$this->entryText = $entryText;
}
public function getId() {
return $this->id;
}
public function getAuthorName() {
return (String) $this->authorName;
}
public function getAuthorMail() {
return (String) $this->authorMail;
}
public function getEntryDate() {
return date('d.n.Y', $this->entryDate);
}
public function getEntryText() {
return $this->entryText;
}
public function setAuthorName($authorName) {
$this->authorName=$authorName;
}
public function setAuthorMail($authorMail) {
$this->authorMail=$authorMail;
}
public function setEntryDate($entryDate) {
$this->entryDate=$entryDate;
}
public function setEntryText($entryText) {
$this->entryText=$entryText;
}

Your problem is case sensitivity. MySQL column names don't deal with camel case, but PHP see's a difference between properties based on case such as $entryDate and $entrydate. Stick to lowercase with underscores if you need visual seperation. The reason why id works is it's all lower case.
I think if you simply lowercase all your property names that are supposed map to table columns everything will work.
BTW... The camel case issue with column names may vary based on the OS running the sql server.

Related

Php language class usage issue

My php multilanguage class returns translated text by field when i call the class. I use echo for return translated text because i fetch whole page in class and translate them in foreach. Problem is when i return translated text with echo, $lang->Translate("PLANT") it jumps outside where i put it. How can i solve this issue. (By the way i can't use just return it only returns 1 row of language table)
The Language Table
echo '
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead class="thead-light">
<tr>
<th scope="col"></th>
<th scope="col"><b></b></th>
<th scope="col"><b>'.$lang->Translate("PLANT").'</b></th>
<th scope="col" class="d-none d-sm-table-cell"><b>'.$lang->Translate("COMPANY").'</b></th>
<th scope="col" class="d-none d-sm-table-cell"><b></b></th>
<th scope="col" class="d-none d-sm-table-cell"><b></b></th>
<th scope="col" class="d-none d-sm-table-cell"><b></b></th>
<th scope="col" class="d-none d-sm-table-cell"><b></b></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
';
my language class
class Lang {
public function Language()
{
static $table = array();
static $loaded = false;
if (!$loaded) {
$loaded = true;
$lang = strtoupper(substr($_SERVER["HTTP_ACCEPT_LANGUAGE"], 0, 2));
include("settings.php"); //DB Connection
$sql = $MYSQLdb->prepare("SELECT * FROM language");
$sql->execute();
while($print = $sql->fetch(PDO::FETCH_ASSOC))
{
$field = array($print["FIELD"] => $print[$lang]);
array_push($table, $field);
}
return $table;
} else {
return $table;
}
}
public function Translate($translate)
{
$table = $this->Language();
foreach($table as $fields) {
echo $fields[$translate];
}
}
}
$lang = new Lang();
As when you do this
$field = array($print["FIELD"] => $print[$lang]);
you are making an array of word,translation i.e.
COMPANY ENTERPRISE
PLANT PLANTE
I see no reason why you cannot return the translation from this method I would change the method slightly as there seems to be no reason for a loop.
public function Translate($translate)
{
$table = $this->Language();
return $table[$translate];
}
Or even like this so you dont need to make a copy of the array
public function Translate($translate)
{
return $this->Language()[$translate];
}
I could go into further improvements to your class but I will focus on your particular issue.
In short change echo to return and the output will be included in your table markup:
public function Translate($translate)
{
$table = $this->Language();
foreach($table as $fields) {
return $fields[$translate];
}
}
Now that is only going to work if that function always returns 1 word because it is going to exit your foreach loop. If the foreach is not neccessary then do this instead (as now mentioned by #RiggsFolly):
public function Translate($translate)
{
$table = $this->Language();
return $table[$translate];
}

Can't Loop The Data in Codeigniter HTML Table

I want to create a loop for my database result. But I can't make it work on my VIEW file.
So here's my model:
<?php class Dash_model extends CI_Model {
public function __construct()
{
parent::__construct();
// Loading second db and running query.
$CI = &get_instance();
//setting the second parameter to TRUE (Boolean) the function will return the database object.
$this->db2 = $CI->load->database('db2', TRUE);
}
public function query0()
{
$query = $this->db2->query("SELECT name FROM table1 ORDER BY date");
return ($query->result());
}
public function query1()
{
$query = $this->db->query("MY QUERY HERE, RUNS OK");
$result = $query->result_array();
return $result;
}
public function query2()
{
$query = $this->db->query("MY QUERY HERE, RUNS OK");
$result = $query->result_array();
return $result;
}
public function query3()
{
$query = $this->db->query("MY QUERY HERE, RUNS OK");
$result = $query->result_array();
return $result;
}
public function query4()
{
$query = $this->db->query("MY QUERY HERE, RUNS OK");
$result = $query->result_array();
return $result;
}
}
Let's say that my query works ok, I've tested it on my SQL Server. And then here's my CONTROLLER:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Dash_control extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->model('dash_model');
$this->load->library('table');
}
public function index()
{
$tmpl = array (
'row_start' => '<tr>',
'row_end' => '</tr>',
'cell_start' => '<td>',
'cell_end' => '</td>',
);
$this->table->set_template($tmpl);
$data['result0'] = $this->dash_model->query0();
$data['result1'] = $this->dash_model->query1();
$data['result2'] = $this->dash_model->query2();
$data['result3'] = $this->dash_model->query3();
$data['result4'] = $this->dash_model->query4();
$this->load->view('dashboard',$data);
}
}
So i have 5 function in my model, the result was supposed to be a LOOP data. After I put the model inside my CONTROLLER, I pass it to my VIEW file like this:
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>Name</th>
<th>Transaction Success</th>
<th>Transaction Failure</th>
<th>Total Visit</th>
<th>Total Item</th>
</tr>
</thead>
<tbody>
<?php foreach (array_combine($result0, $result1, $result2, $result3, $result4) as $row)
{ ?>
<tr>
<td><?php echo $row->queryalias0; ?></td>
<td><?php echo $row->queryalias1; ?></td>
<td><?php echo $row->queryalias2; ?></td>
<td><?php echo $row->queryalias3; ?></td>
<td><?php echo $row->queryalias4; ?></td>
</tr>
<?php } ?>
</tbody>
</table>
The error I got was:
Message: array_combine(): Both parameters should have an equal number of elements
And:
Message: Invalid argument supplied for foreach()
The result that I would like to achieve should be like this:
Thank you guys, for all your help...
From php.net
array_combine — Creates an array by using one array for keys and
another for its values
array array_combine ( array $keys , array $values )
You using wrong way array_combine function. You can try array_merge instead
foreach (array_merge($result0, $result1, $result2, $result3, $result4) as $row)

PHP - query worked but the results are strange : all null

I use a data base ( created with phpmyadmin) in a function for my future website. The query worked but the result is strange : null .
This is my code :
public function select_toutcompetences($requete){
$query = "SELECT niv , nom FROM competences WHERE element = '$requete' ";
$result = $this->_db->query($query);
$tableau = array();
if ($result->rowCount() == 0){
return $tableau;
} else {
while($row = $result->fetch()) {
$tableau[] = new Competence($row->niv,$row->nom);
}
return $tableau;
}
}
In my view :
<?php if (!empty($table)) {?>
<table>
<caption>Les compétences</caption>
<tr>
<th>Niveau</th>
<th>Nom</th>
<tr>
<?php foreach ($table as $i=> $element) { ?>
<tr>
<td><?php echo $element->niveau()?></td>
<td><?php echo $element->nom()?></td>
</tr>
<?php } ?>
</table>
<?php }?>
With a var_dump , I got this :
object(Competence)[5]
private '_niveau' => null
private '_nom' => null
null
My class :
<?php
class Competence {
private $_niveau;
private $_nom;
public function Livre($niveau,$nom) {
$this->_niveau = $niveau;
$this->_nom = $nom;
}
public function niveau() {
return $this->_niveau;
}
public function nom() {
return $this->_nom;
}
}
?>
Thanks you for your help. I searched but I didn't understand why it doesn't work.
PS : I know my query isn't securized. I would it to work first.
Edit : the sql data base : comptences.sql
It is because your class does not have constructor. Method Livre is not called when object is initiating $tableau[] = new Competence($row->niv,$row->nom);. Try this (I have replaced Livre with __construct):
<?php
class Competence {
private $_niveau;
private $_nom;
public function _contruct($niveau,$nom) {
$this->_niveau = $niveau;
$this->_nom = $nom;
}
public function niveau() {
return $this->_niveau;
}
public function nom() {
return $this->_nom;
}
}
Also be sure you have same values in database result.
Try making the variables in your class public as well.
public $_niveau;
public $_nom;

Show all users in a table and delete those selected

how can I show all the users in the users table in the database in a html table?
I have to show all the users in a html table and each user can be selected using a check box. The selected users are then deleted from the database.
I am using the technique mvc and I have a page "DeleteUser" that contains only the html, a controller and a public file.
View/DeleteUser.php contains:
<form method="post" action="../public/deleteUser.php">
<table>
<tr>
<td>#</td>
<td>Username</td>
<td>First name</td>
<td>Last name</td>
<td>City</td>
<td>Gender</td>
<td>E-mail</td>
<td>Check</td>
</tr>
<tr>
<td><input type="submit" name="submit-deleteuser" value="Delete user"/></td>
</tr>
</table>
</form>
public/deleteUser.php contains:
$controller = new DeleteUserController();
$view = $controller->invoke();
$view->render();
The invoke() method in Controller/DeleteUserController.php contains:
class DeleteUserController {
public $user;
public $users;
public $userRepository;
public $view;
public function __construct() {
$username = $_SESSION['username'];
$this->userRepository = new UserRepository();
$this->user = $this->userRepository->findByUsername($username);
$this->users = array();
$this->view = new View('DeleteUser');
$db = Database::getInstance();
}
public function listUsers() {
$this->users = $this->userRepository->fetchAll();
foreach($this->users as $u) {
$str = "<tr>
<td><?php $u->getId() ?></td>
</tr>";
}
}
public function deleteUsers() {
if(isset($_POST['submit-deleteuser'])) {
$del_id = $_POST['users'];
foreach($del_id as $value) {
$value->delete();
}
}
}
public function work() {
$this->listUsers();
$this->deleteUsers();
}
public function invoke() {
$this->work();
$this->view->setData('user', $this->user);
return $this->view;
}
If I had not had to use mvc I would have done so:
<table>
<tr>
<td>#</td>
<td>Username</td>
<td>Fisrt name</td>
<td>Last name</td>
<td>City</td>
<td>Gender</td>
<td>E-mail</td>
<td>Check</td>
</tr>
<?php
$utente = $_SESSION['username'];
$query = "SELECT * FROM users ORDER BY id";
$result = mysql_query($query);
while($row = mysql_fetch_array($result)) {
echo "<tr>
<td>$row[id]</td>
<td>$row[username]</td>
<td>$row[fisrt_name]</td>
<td>$row[last_name]</td>
<td>$row[city]</td>
<td>$row[gender]</td>
<td>$row[email]</td>
<td><input type=\"checkbox\" name=\"users[]\" value=\"" .$row['id']. "\"></td>
</tr>";
}
}
?>
<tr>
<td colspan="9"><input type="submit" name="submit-deleteuser" value="Delete users"/></td>
</tr>
</table>
But now I do not know how to do. The two methods listUsers() and deleteUsers() are wrong and do not know how to complete them or correct them.
First it was simple, I put the php code that showed users in the html tag that I wanted (<table>...</table>) but now?
I do not know how to handle this thing.
Give me advice? Thank you :)
fetchAll() is:
public function fetchAll(){
$db = Database::getInstance();
$stmt = $db->prepare("SELECT * FROM `users`");
$stmt->execute();
$users = array();
while($result = $stmt->fetch()) {
$users[] = User::load($result);
}
return $users;
}
The attempt to use the MVC pattern is admirable, but a little bit off in this case :). What is missing, is the concept of controller actions.
Maybe try to restructure your code something like this:
Directory Structure
controllers/
UsersController.php
models/
UsersModel.php
core
View.php
views/
header.tpl.php
footer.tpl.php
users/
list.tpl.php
delete.tpl.php
users.php
1. Start with a users model that interacts with the database
class UsersModel {
public function fetchAll() {
$result = array();
// Build SELECT query, fetch all users from db., and store in $result
// ...
return $result;
}
public function deleteMany(array $ids) {
$result = array();
// Build DELETE query, execute it, and store the number of affected records in $result
// ...
return $result;
}
}
2. Make a UsersController instead of a DeleteUserController. Create two methods: listUsersAction and deleteUsersAction.
class UsersController {
public function listUsersAction() {
$model = new UsersModel();
$data = $model->fetchAll();
return new View(
'users/list',
$data
);
}
public function deleteUsersAction() {
// This is simplistic, but the idea is to get the required input from the request (and actually validate it!)
// Also see the users/list template further down
$ids = $_POST['user_ids'];
$model = new UsersModel();
$numRecords = $model->deleteMany($ids);
return new View(
'users/delete',
array('deleted_records' => $numRecords)
);
}
}
3. Our View class should store the template name and the view data, and be able to render the template
class View {
public static $viewDirectory;
public $template;
public $data = array();
public function __construct($template, $data) {
if (!View::$viewDirectory) {
View::$viewDirectory = dirname(__FILE__) . '/views/';
}
$this->template = $template;
$this->data = $data;
}
public function render() {
// Make the data available in the template
$data = $this->data;
// Include the template.
require(realpath(View::$viewDirectory . $this->template . '.tpl.php'));
}
}
4. The users/list template could then look something like this
// views/users/list.tpl.php
<form action="/users.php?action=delete" method="post">
<?php foreach ($data as $user): ?>
<div>
<input type="checkbox" name="user_ids[<?= $user['id'] ?>]" value="1"/>
<?= $user['username'] ?>
</div>
<?php endforeach; ?>
</form>
5. Tie everything together in users.php
<?php
// users.php
// (include all previously defined classes here)
// We'll want to include a HTML header of some sort:
include("views/header.tpl.php");
/**********
* Poor man's routing; valid urls:
* /users.php?action=listUsers
* /users.php?action=deleteUsers with POST data
*/
// Determine the action from the GET parameter. If no action is set, the default action is listUsers
//$action = (array_key_exists('action', $_GET) ? $_GET['action'] : 'listUsers');
// Equivalent of:
if (array_key_exists('action', $_GET)) {
$action = $_GET['action'];
} else {
$action = 'listUsers';
}
//--
$actionMethod = $action . 'Action';
$controller = new UsersController();
if (method_exists($controller, $actionMethod)) {
$view = $controller->$actionMethod();
$view->render();
} else {
echo "<div class='error'>The action '$action' is invalid for the Users controller.'</div>";
}
// We'll want to include a footer as well:
include("views/footer.tpl.php");
?>

Fatal error: Declaration of .. must be compatible with .. PHP

I'm getting the following error:
Fatal error: Declaration of Shoppingcart::addToCart() must be compatible with that of Ishoppingcart::addToCart() in klassen.php on line 118
What could be the problem? I can't find it
script:
<?php
// begin
interface Ishoppingcart{
public function addToCart();
public function printOverzicht();
}
abstract class Shoppingcart implements Ishoppingcart
{
protected $producten = array();
public function addToCart( Product $product) {
$this->producten[] = $product;
}
}
class Myshoppingcart extends Shoppingcart {
public function printOverzicht(){
echo ("<table border=1>
<tr>
<td colspan='7'>Bestellingoverzicht</td>
</tr>
<tr>
<td bgcolor=#cccccc> Product ID</td>
<td bgcolor=#cccccc> Beschrijving</td>
<td bgcolor=#cccccc> Merk</td>
<td bgcolor=#cccccc> Model</td>
<td bgcolor=#cccccc> Prijs</td>
<td bgcolor=#cccccc> Aantal</td>
<td bgcolor=#cccccc> Korting</td>
</tr>");
foreach($this->producten as $product){
$rij = "";
$rij .= "<tr>";
$rij .= "<td>".$product->getID()."</td>";
$rij .= "<td>".$product->getBeschrijving()."</td>";
$rij .= "<td>".$product->getMerk()."</td>";
$rij .= "<td>".$product->getModel()."</td>";
$rij .= "<td>".$product->getPrijs()."</td>";
$rij .= "<td>".$product->getAantal()."</td>";
$rij .= "<td>".$product->getKorting()."</td>";
$rij .= "</tr>";
echo ($rij);
}
echo ("</table>");
}
}
class Product {
private $id;
private $beschrijving;
private $merk;
private $model;
private $prijs;
private $aantal;
private $korting;
function __construct($id,
$merk,
$model,
$prijs,
$aantal,
$korting){
$this->id = $id;
$this->beschrijving = $beschrijving;
$this->merk = $merk;
$this->model = $model;
$this->prijs = $prijs;
$this->aantal = $aantal;
$this->korting = $korting;
echo ("<br />Nieuw Product object $beschrijving wordt aangemaakt");
}
public function __destruct(){
// voer benodigde acties uit
echo ("<br />Product object $this->beschrijving wordt verwijderd");
}
// set function
public function setId($id){
$this->id = $id;
}
public function setBeschrijving($beschrijving){
$this->beschrijving = $beschrijving;
}
public function setMerk($merk){
$this->merk = $merk;
}
public function setModel($model){
$this->model = $model;
}
public function setPrijs($prijs){
$this->prijs = $prijs;
}
public function setAantal($aantal){
$this->aantal = $aantal;
}
public function setKorting($korting){
$this->korting = $korting;
}
// get function
public function getId(){
return $this->id = $id;
}
public function getBeschrijving(){
return $this->beschrijving;
}
public function getMerk(){
return $this->merk;
}
public function getModel(){
return $this->model;
}
public function getPrijs(){
return $this->prijs;
}
public function getAantal(){
return $this->aantal;
}
public function getKorting(){
return $this->korting;
}
// printProductInfo
public function printProductInfo(){
$rij = "<tr><td>$this->id</td>";
$rij .= "<td>$this->beschrijving</td>";
$rij .= "<td>$this->merk</td>";
$rij .= "<td>$this->model</td>";
$rij .= "<td>$this->prijs</td>";
$rij .= "<td>$this->aantal</td>";
$rij .= "<td>$this->korting</td>";
echo ($rij);
}
}
// einde
?>
Ishoppingcart::addToCart() states that the method does not take any parameter, while the implementation Shoppingcart::addToCart(Product $product) requires that a parameter of type Product must be passed into the method. This means that both declarations are incompatible and while the implemented interface must be satisfied PHP throws the shown error.
Solution would be to either change Ishoppingcart::addToCart() to Ishoppingcart::addToCart(Product $product) so that it requires a parameter of type Product or to change Shoppingcart::addToCart(Product $product) to allow no parameter to passed into the method: Shoppingcart::addToCart(Product $product = null);
The correct way depends on your application requirements.
The declaration of a public function in a sub class must match that of its parent:
public function addToCart();
public function addToCart( Product $product)
You cannot add a parameter to the signature.
This is closely related to the Liskov substitution principle.
Doesn't apply to this particular question, but if someone there is having this issue, make sure to include the return value if the Interface specifies it.
An interface with a function like this:
abstract public function crawled(Something $some): void;
needs to be implemented as:
public function crawled(Something $some): void {
}
In my case I was missing the : void return type.
Interface Ishoppingcart seems to define addToShoppingCart without parameters, but class Shoppingcart defines the same function taking Product as a parameter. I suppose the method in the interface should take Product as a parameter as well.
I resolved this issue by upgrading to the latest php version
This can also happen if Intelephense sees multiple classes with the same name but with different signatures. They may not be in PHP's scope, but Intelephense allows specifying additional directories and seems to pick up backup directories and the like as well.

Categories