Can you explain me why this isn't working? I'm storing PDO fetch into PHP class variable and then I'm trying to loop it using function call.
PHP class
private $conn;
private $id;
private $data = array();
public function __construct($conn, $id) {
$this->id = $id;
$this->loadData();
}
private function loadData() {
$sql = $this->conn->prepare("SELECT * FROM table WHERE id = :id");
$sql->bindValue(':id', $this->id);
$sql->execute();
$this->data = $sql->fetch();
}
public function getData() {
return $this->data();
}
Script itself
$test = new test($pdo, "100101");
while ($row = $test->getData()) {
echo $row['item'];
}
There will only be loop as long as the memory limit has been reached. Query should return ca. 20 rows only.
Thanks in advance!
change fetch() to fetchAll()
change while to foreach ($test->getData() as $row)
Related
I am new in PHP OOP and was wondering if someone could help me with this.
I have a basic class with one method which returns data from database. Currently I am calling the method which displays everything inside the function.
Here is my class Definition:
class Products{
//properties
public $familyName = "";
public $familyProduct = "";
//Methods
public function getFamily($catId){
global $conn;
$sql = "SELECT * FROM product_family WHERE catID = '$catId'";
$result = $conn->query($sql);
if($result->num_rows > 0){
while($row = $result->fetch_assoc()){
echo "<li>".$row['familyName']."</li>";
echo "<li>".$row['familyProduct']."</li>";
}
}
}
}
Here is how I call the method:
$Products = new Products;
$Products->getFamily( 4 );
This works however, how can I assign each data coming from database ( ex familyName, familyProduct ) into variables inside class implementation and then access them individually where ever I need to. Something like this:
$Products = new Products;
$Products->familyName;
$Products->familyProduct;
I have empty properties but I am not sure how can I assign values to them coming from the loop and then return them each.
Thanks,
There are view things I would change in your Code.
Don't make Properties public use use Getters and Setters.
This will protect you Object from being used the wrong way e.g. now you can't change the familyName from outside: $products->familyName = "some value" because this would make the data of the object corrupt.
global $conn; is a no go in OOP use the construct of the Object,
in your case $products = new Products($conn);
Now you can set a Cat ID $products->setCatId(4); and read the result
$familyName = $products->getFamilyName(); or $familyProduct = $products->getFamilyProduct();
If you have more than one result you will get an array, if catId will always result one row you can delete this part. If you learn more about OOP you will find out that the hole SQL stuff can be done with a separate Object, but this is off Topic.
class Products
{
// Properties
protected $conn;
protected $catId;
protected $familyName;
protected $familyProduct;
public function __construct($conn)
{
$this->conn = $conn;
}
// set Cat ID and get date
public function setCatId($catId)
{
$this->catId = (int) $catId;
$this->getDate();
}
public function getCatId()
{
return $this->catId;
}
// get Family Name
public function getFamilyName()
{
return $this->familyName;
}
// get Family Product
public function getFamilyProduct()
{
return $this->familyProduct;
}
// get date
protected function getDate()
{
$sql = "SELECT * FROM product_family WHERE catID = '$this->catId'";
$result = $this->conn->query($sql);
// Default if no result
$this->familyName = null;
$this->familyProduct = null;
// if one Result
if ($result->num_rows == 1)
{
$row = $result->fetch_assoc();
$this->familyName = $row['familyName'];
$this->familyProduct = $row['familyProduct'];
}
if ($result->num_rows > 1)
{
$this->familyName = [];
$this->familyProduct = [];
while ($row = $result->fetch_assoc())
{
$this->familyName[] = $row['familyName'];
$this->familyProduct[] = $row['familyProduct'];
}
}
}
}
I've written a class which in the construct accesses the db and gets a list of names. These names go into an associative array e.g. ('name' => 'id').
i.e. the point is to pass in the name to get back an ID:
$id = names::nameToId('some name');
print $id;
// prints int
The problem is when I try and return the array from the construct I get an error:
Notice: Undefined variable: nameArray in (etc)
Here is the code so far:
class nameToId {
public $nameArray;
private $mysqli;
public function __construct($mysqli) {
...
while($row = mysqli_fetch_assoc($res)) {
$nameArray[$row['name']] = $row['id'];
}
return $nameArray;
}
static public function nameToId($name) {
$nameId = $nameArray[$name];
return $nameId;
}
}
$namesToId = new nameToId($mysqli);
$nameId = $namesToId::nameToId('some name');
echo $nameId;
Why doesn't $nameArray get passed to nameToId()? I'm new to classes, and I thought by declaring $nameArray as public when I first create the class that it would make it available. I have also tried to make it global even though I know that is not good form but even still it didn't work.
Because you cannot return anything from a constructor. Any return value is being ignored and just goes into the aether. $nameArray is a local variable and is not shared in any other scope, i.e. you can't access it in nameToId. Further, since nameToId is static, it won't have access to data from any non-static methods like __construct to begin with.
You probably want something like this:
class nameToId {
public $nameArray;
private $mysqli;
public function __construct($mysqli) {
...
while ($row = mysqli_fetch_assoc($res)) {
$this->nameArray[$row['name']] = $row['id'];
}
}
public function nameToId($name) {
return $this->nameArray[$name];
}
}
$namesToId = new nameToId($mysqli);
echo $namesToId->nameToId('some name');
Fix your code:
class nameToId {
public static $nameArray;
private $mysqli;
public function __construct($mysqli) {
$this->mysqli = $mysqli;
$sql = 'SELECT id, name FROM teams';
$res = mysqli_query($this->mysqli,$sql);
while($row = mysqli_fetch_assoc($res)) {
self::$nameArray[$row['name']] = $row['id'];
}
}
static public function nameToId($name) {
$nameId = self::$nameArray[$name];
return $nameId;
}
}
$namesToId = new nameToId($mysqli);
$nameId = $namesToId::nameToId('some name');
echo $nameId;
I am using PHP with OOP to select rows from the database (MySQL).
When I execute the query, it returns an empty row.
Here is the classe I am using:
<?php
class EmploiManager
{
private $_db;
public function __construct($db)
{
$this->setDb($db);
}
public function category($category)
{
$q = $this->_db->prepare('SELECT * FROM DemandeEmploi WHERE category = :category');
$q->execute(array('category' =>$category));
$donnees = $q->fetch(PDO::FETCH_ASSOC);
return new Emploi($donnees);
}
public function setDb(PDO $db)
{
$this->_db = $db;
}
}
$type = $_GET['category'];
$manager = new EmploiManager($db);
$row = $manager->category($type);
foreach ($row as $demandeE)
{
?>
<div class="list"><h4><? echo $demandeE->title();?></h4> </div>
<?php
}
?>
Can any one tell me what's wrong with that code?
Thanks!
It's my bad, I didn't use a loop to select all the rows.
I corrected the code and it works fine now, here is what it looks like:
public function category($category)
{
$datas = array();
$q = $this->_db->prepare('SELECT * FROM DemandeEmploi WHERE category = :category');
$q->execute(array('category' =>$category));
while ($donnees = $q->fetch(PDO::FETCH_ASSOC))
{
$datas[] = new Emploi($donnees);
}
return $datas;
}
$q->fetch() just returns one row of the results. If you want all the results, you must use $q->fetchAll().
Since you specified PDO::FETCH_ASSOC, the elements of $row will be associative arrays, not objects; aren't you getting errors saying that you're trying to call a method on a non-object? So $demandeE->id() should be $demandeE['id'], and $demandeE->title() should be $demandeE['title'].
Alternatively, you could specify PDO::FETCH_OBJ. Then, the values will be properties, not methods, so it should be $demandeE->id and $demandeE->title (no parentheses).
Hi I have a couple of php classes. And I am passing a connection to a MySql database.
When I make an instance of the firs class and try to call the invoice class with the method getinvoicedetails() I get error "Command out of sync; you can't run this command".
Any help wil be appreciated.
Here is the code:
<?php //Invoicectrl class
class invoicectrl
{
// define properties
public $invoices = Array();
public $connection;
public $userID;
public $ownerID;
// constructor
public function __construct($userIDin,$ownerIDin) {
$this->userID = $userIDin;
$this->ownerID = $ownerIDin;
}
//function to set connection to db
public function setconnection($conn){
$this->connection = $conn;
}
public function getinvoicelist(){
$res = Array();
$invIDs = Array();
//Get list of invoicenumbers and invoiceIDs
$queryd = "CALL sp_getOwnersInvNumIDs (".$this->ownerID.")";
$result = $this->connection->query($queryd) or die($this->connection->error.__LINE__);
// GOING THROUGH invoices and getting there data
$o=0;
while($row = $result->fetch_assoc()) {
$invIDs[$o]['ID'] = $row['invoiceID'];
$invIDs[$o]['NR'] = $row['invoicenumber']; }
$result->free();
//Set each invoice own info
for($i=0;$i<=count($invIDs)-1;$i++){
$res[$i] = new invoice($invIDs['ID'],$invIDs['NR']);
$res[$i]->setconnection($this->connection);
$res[$i]->getinvoicedetails();
}
return $res;
}
}
?>
And here is the invoice class
<?php //Invoice class
class invoice
{
// define properties
public $invoiceID;
public $invoicenumber;
public $itemIDs=Array();
public $items= Array();
public $customerID;
public $cust_company;
public $cust_name;
public $cust_email;
public $cust_adress1;
public $cust_adress2;
public $cust_adress3;
private $connection;
// constructor
public function __construct($invoiceIDin,$invoicenumberin) {
$this->invoiceID = $invoiceIDin;
$this->invoicenumber = $invoicenumberin;
}
//function to set connection to db
public function setconnection($conn){
$this->connection = $conn;
}
//sets all invoices details
public function getinvoicedetails(){
//Get customer on invoice
$queryd = "select customerID FROM Accounting_Invoice_Customer where invoiceID =".$this->invoiceID."";
$result = $this->connection->query($queryd) or die($this->connection->error.__LINE__);
while($row1 = $result->fetch_assoc()) {
$this->customerID = $row1['customerID'];
}
$result->free();
//Get list of items on invoice
$queryd = "call sp_getItems(".$this->invoiceID.")";
$result = $this->connection->query($queryd) or die($this->connection->error.__LINE__);
$o=0;
while($row2 = $result->fetch_assoc()) {
$this->items[$o]['itemID'] = $row2['itemID'];
//$this->items[$o]['itemnumber'] = $row['itemnumber'];
//$this->items[$o]['itemdescription'] = $row['itemdescription'];
//$this->items[$o]['itempricewotax'] = $row['itempricewotax'];
$o++;
}
$result->free();
}
}
?>
When you run a SQL request, you have to get through the whole result or to close the cursore before sending another request.
The best thing to do, here is to get the whole result at first and then traverse it with a foreach loop to be able to send the second request.
Moreover, it should be a good idea to use INNER JOIN in your sql query.
$queryd = "CALL sp_getOwnersInvNumIDs (".$this->ownerID.")";
$result = $this->connection->query($queryd) or die($this->connection->error.__LINE__);
$invIDs = $result->fetch_all();
$res = array();
foreach($invIDs as $inv){
$inv = new invoice($invIDs['invoiceID'],$invIDs['invoiceNumber']);
$inv->setconnection($this->connection);
$inv->getinvoicedetails();
$res[] =$inv;
}
I'm a little confused at the moment because my DB class doesn't seem to be storing any results after a query (i.e. the 'results' property is still an empty array). The unsual thing is that when I transfer my logic outside a class definition it works perfectly.
My code with database credentials blanked out:
namespace DatabaseConnection;
use PDO;
class DB {
/*****STATES*****/
private $con;
private $results;
/*****METHODS*****/
public function init(){
$this->con = new PDO("***************************");
$this->results = array();
return $this;
}
public function getInfo(){
if($this->con === null ) return "No Connection";
else return "Connected";
}
public function getResults(){
return $this->results;
}
public function retrieve(){
$query = $this->con->prepare("select * from documents");
$query->execute();
while($row = $query->fetch(PDO::FETCH_ASSOC)){
$this->results[] = $row;
}
return $this;
}
Try:
public function retrieve(){
$query = $this->con->prepare("select * from documents");
$query->execute(); //<---------
while($row = $query->fetch(PDO::FETCH_ASSOC)){
$this->results[] = $row;
}
return $this;
}
OP is preparing a statement and then never executes it, and has no way of detecting this because of the utter lack of any error handling on the DB calls. – Marc B