php scope: class object cant be seen in function - php

I have a simple mysqli wrapper class I use for my database operations. I am defining (instantiating?) that class at the top of the code presumably where it should be globally accessable, however when I try to use this reference to the db class within a recursive function, xdebug tells me it is out of scope - so as a fix I have had to define the database twice, but this seems like poor practice. Can anyone tell whats up or where I'm going wrong?
The code is recursively printing nested comments from the database FYI.
The code is as follows...
<?php
require 'lib/mysqli.class.php'; // the pretty standard mysqli class
$config = array();$config['host'] = 'localhost';$config['user'] = 'root';$config['pass'] = '';$config['table'] = 'publicate';
$db = new DB($config); // new instance of database
//$db->setFetchMode(2); // fetch data by association (MYSQLI_ASSOC)
// Run a Query:
$db->query('SELECT * FROM comments WHERE parentid = 0');
// Get the data:
$root_sql = $db->get();
recursive_categories($root_sql);
function recursive_categories($results)
{
if(count($results))
{
echo "<ul>";
foreach($results as $res)
{
echo "<li>" . "id=" . $res['id'] . ", pid=" . $res['parentid'] . ", content: " . $res['content'];
//Rest of what ever you want to do with each row
//Check this category for children ************************
//2nd definition of DB ************************
$config = array();$config['host'] = 'localhost';$config['user'] = 'root';$config['pass'] = '';$config['table'] = 'publicate';
$db2 = new DB($config); // new instance of database
$db2->query("SELECT * FROM comments WHERE parentid = " . $res['id']);
$rows = $db2->get();
recursive_categories($rows);
//has to be after the inner loops
echo "</li>";
}
echo "</ul>";
}
}
?>
Thanks.

You need to pass your $db connection to the function like so:
function recursive_categories($results, $db)
Then it will be available inside the function variable scope.
Another issue that comes to mind ... If this file resides inside a publicly accessible web directory you definitely don't want to have your actual database credentials just chilling there out in the open.

Related

Unable to use the PHP Simple HTML DOM Parser's find() function

I am trying to scrape a remote website and edit parts of the results before updating a couple of tables in the database and subsequently echo()'ing the final document.
Here's a redacted snippet of the code in question for reference:
<?php
require_once 'backend/connector.php';
require_once 'table_access/simplehtmldom_1_5/simple_html_dom.php';
require_once 'pronunciation1.php';
// retrieve lookup term
if(isset($_POST["lookup_term"])){ $term = trim($_POST["lookup_term"]); }
else { $term = "hombre"; }
$html = file_get_html("http://www.somesite.com/translate/" . rawurlencode($term));
$coll_temp = $html->find('div[id=translate-en]');
$announce = $coll_temp[0]->find('.announcement');
$quickdef = $coll_temp[0]->find('.quickdef');
$meaning = $announce[0] . $quickdef[0];
$html->clear(); // release scraper variable to prevent memory leak issues
unset($html); // release scraper variable to prevent memory leak issues
$meaning = '<?xml version="1.0" encoding="ISO-8859-15"?>' . $meaning;
// process the newly-created DOM
$dom = new DOMDocument;
$dom->loadHTML($meaning);
// various DOM-manipulation code snippets
// extract the quick definition section
foreach ($dom->find('div[class=quickdef]') as $qdd) {
$qdh1 = $qdd->find('.source')[0]->find('h1.source-text');
$qdterm = $qdh1[0]->plaintext;
$qdlang = $qdh1[0]->getAttribute('source-lang');
add2qd($qdterm, $qdd, $qdlang);
unset($qdterm);
unset($qdlang);
unset($qdh1);
}
$finalmeaning = $dom->saveHTML(); // store processed DOM in $finalmeaning
push2db($term, $finalmeaning); // add processed DOM to database
echo $finalmeaning; // output processed DOM
// release variables
unset($dom);
unset($html);
unset($finalmeaning);
function add2qd($lookupterm, $finalqd, $lang){
$connect = dbconn(PROJHOST, CONTEXTDB, PEPPYUSR, PEPPYPWD);
$sql = 'INSERT IGNORE INTO tblquickdef (word, quickdef, lang) VALUES (:word, :quickdef, :lang)';
$query = $connect->prepare($sql);
$query->bindParam(':word', $lookupterm);
$query->bindParam(':quickdef', $finalqd);
$query->bindParam(':lang', $lang);
$query->execute();
$connect = null;
}
function push2db($lookupword, $finalmean) {
$connect = dbconn(PROJHOST, DICTDB, PEPPYUSR, PEPPYPWD);
$sql = 'INSERT IGNORE INTO tbldict (word, mean) VALUES (:word, :mean)';
$query = $connect->prepare($sql);
$query->bindParam(':word', $lookupword);
$query->bindParam(':mean', $finalmean);
$query->execute();
$connect = null;
}
?>
The code works fine except for the for loop under the // extract the quick definition section. The function being called from inside this loop is add2qd() which accepts 3 string values as input.
Every time this loop runs, PHP throws a fatal error because it thinks find() is undefined. I know find is a legitimate function in the PHP Simple HTML DOM Parser library because I have used it multiple times in the same code without any problem (in the //retrieve lookup term section). What am I doing wrong?
But your are not using the PHP Simple HTML DOM - only standard PHP DOMDocument, which does not have the method find.
$dom = new DOMDocument;
$dom->loadHTML($meaning);
foreach ($dom->find('div[class=quickdef]') as $qdd) {
http://php.net/manual/en/class.domdocument.php

Get Array from PHP file and use in another PHP file

So i am having trouble getting an array from one PHP file to another.
In my first file (file1.php) i got following code:
print_r($order->delivery);
It will get visible when using echo of course, and it outputs the right things. It gives me an array with order information. Now i got another PHP file I need to use this information in.
What i tried so far is including file1.php to file2.php and then echo the array... But the result is empty.
require_once('path/file1.php');
echo print_r($order->delivery);
And i tried echo my array directly in file1.php adding a div like this
echo "<div id='test'>" . print_r($order->delivery, true) . "</div>";
And then getting the inner HTMl of the div with DOM
$dom = new DOMDocument();
$dom->loadHTML("mypageurl");
$xpath = new DOMXPath($dom);
$divContent = $xpath->query('//div[id="test"]');
if($divContent->length > 0) {
$node = $divContent->item(0);
echo "{$node->nodeName} - {$node->nodeValue}";
}
else {
// empty result set
}
Well... none of it works. Any suggestions?
You have to set a variable or something, not echoing it.
file1.php:
$delivery = $order->delivery;
file2.php
include('path/file1.php');
echo "<div id='test'>" . (isset($delivery['firstname']) ? $delivery['firstname'] : '') . "</div>";
Or you use the $object directly if it is set in file1.php
file2.php
include('path/file1.php');
echo "<div id='test'>" . (isset($order->delivery['firstname']) ? $order->delivery['firstname'] : '') . "</div>";
You can do this by using $_SESSION or $_COOKIE, See here for more detail; PHP Pass variable to next page
Be careful at the variable scope. See this link: http://php.net/manual/en/language.variables.scope.php
And try this code please:
require_once('path/file1.php');
global $order;
print_r($order->delivery);
Defining $order as global should fix your issue.
You could return an array in a file and use it in another like this:
<?php
/* File1.php */
return array(
0,1,2,3
);
-
<?php
/* File2.php */
var_dump(require_once('File1.php'));

PHP: Fatal error: Call to a member function appendChild() on a non-object in

I am trying to use data entered by the user to store it into an XML Database file for use further down the line. However, for some reason I continue to get this error.
The problem code is summarised below and the whole PHP file is below that for context.
I have tried converting the integer I got (I was using mt_rand() before using uniqid()) using strval(), also tried Type Casting to (string), even tried Type Casting to (object). All no luck. uniqid() returns a string already. In fact, the error returned when I try Type Casting to object (both from uniqid() and mt_rand()) was different, and made life confusing:
[![Error 2 Where the output of idGenerated is an object][2]][2]
Why oh why does a createTextNode hate Strings, Integers AND Objects?? And why do the other variables in the file (undergoing the SAME process) pass by absolutely fine?
Summarised Problem Code
$idGenerated = uniqid();
$dom = new DOMDocument();
$dom->load('../test.xml');
$idDec = $dom->createTextNode($idGenerated);
$id->appendChild($idDec);
$messageElement->appendChild($id);
Whole File:
<?php
session_start();
//Generate random number to avoid overwrite of file
$randomNumber = mt_rand(10, 99);
move_uploaded_file($_FILES['attachment'][tmp_name], "../uploads/" . $randomNumber . $_FILES['attachment'][name]);
//General Variables
***$idGenerated = uniqid();***
$currentDate = date('l jS \of F h:i:s A');
$sender = $_SESSION['user'];
$message = $_POST['messageText'];
$up_file = $randomNumber . $_FILES['attachment'][name];
$up_file_location = "uploads/" . $up_file;
echo "<br>";
var_dump($currentDate);
echo "<br>";
var_dump($sender);
echo "<br>";
var_dump($message);
echo "<br>";
var_dump($up_file);
echo "<br>";
var_dump($up_file_location);
$dom = new DOMDocument();
$dom->load('../test.xml');
//Dom Variable Declarations
//Declare String Data
***$idDec = $dom->createTextNode($idGenerated);***
$date = $dom->createTextNode($currentDate);
$name = $dom->createTextNode($sender);
$messageText = $dom->createTextNode($message);
$link = $dom->createTextNode($up_file_location);
$linkName = $dom->createTextNode($up_file);
//Declare Data Elements
$id = $dom->createElement('id');
$timecode = $dom->createElement('timecode');
$author = $dom->createElement('author');
$content = $dom->createElement('content');
$filePath = $dom->createElement('filePath');
$fileName = $dom->createElement('fileName');
$messageElement = $dom->createElement('message');
//Create XML Data Structure
//ID
***$id->appendChild($idDec);***
//Date
$timecode->appendChild($date);
//Name
$author->appendChild($name);
//Message
$content->appendChild($messageText);
//File (if there is one!)
$filePath->appendChild($link);
$fileName->appendChild($linkName);
//Message Wrapper Element
***$messageElement->appendChild($id);***
$messageElement->appendChild($timecode);
$messageElement->appendChild($author);
$messageElement->appendChild($content);
$messageElement->appendChild($filePath);
$messageElement->appendChild($fileName);
//Load last existing XML entry for reference (which, since they are all in reverse order, will actually be the FIRST entry in the database)
$xml = simplexml_load_file('../test.xml');
$lastEntry = $xml->log->message[0];
//Place new data BEFORE the last existing message Element
$newEntry = $dom->firstChild->appendChild($messageElement);
$lastEntry->parentNode->insertBefore($newEntry, $lastEntry);
$dom->save('../test.xml');
header("Location: ../index.php");
?>
Whenever you get Call to a member function … on a non-object, you’re using something as an object which at the time of calling is not an object. (This often seen in loops where you access a array element, expecting it to be an object when it’s not.)
But in your case, it’s simply the fact that $messageElement is not defined. Maybe you copy/pasted the code from somewhere else and forgot to copy the initial definition/initialisation of the $messageElement variable.

How to set instance variables in camunda using the PHP SDK?

I am trying to use the PHP SDK in camunda but it is not clearly documented how to set process variables.
Any ideas?
You can do that by using the ProcessInstanceService.
Below is a snippet for the demo Invoice Receipt.
$camundaAPI = new \org\camunda\php\sdk\Api('http://localhost:8080/engine-rest');
$processDefinitionRequest = new \org\camunda\php\sdk\entity\request\ProcessDefinitionRequest();
$processDefinitions = $camundaAPI->processDefinition->getDefinitions($processDefinitionRequest);
foreach($processDefinitions AS $pd) {
echo 'Process deployment id: ' . $pd->getDeploymentId() . "\n";
}
// Process instance (make the assumption that $pd is the desired object).
$procInstance = $camundaAPI->processDefinition->startInstanceByKey($pd->getKey(), $processDefinitionRequest);
// ProcessInstanceService
$procInstanceService = new \org\camunda\php\sdk\service\ProcessInstanceService('http://localhost:8080/engine-rest/');
$var = new \org\camunda\php\sdk\entity\request\VariableRequest();
$var->setType('String');
$var->setValue('H4CK4THON2014');
$procInstanceService->putProcessVariable($procInstance->getId(), 'creditor', $var);

Trying to make an function call to an external file with PhP, MySQL using WAMP

I'm sure there is a simple answer to this, but I have been fumbling with everything for almost a week now and surrender. I am trying to build a shopping cart app and every coding solution I build will work when I include the code on the same page, but when I try to use an external page to run the function it does not seem to return the data. I have tried various monitoring techniques to determine what it is happening.
Here is the code for the main page:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Cart Connection</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
</head>
<body>
<p>Will this display?</p>
<p><a href='<?php echo "showCart.php?PHPSESSID=" . session_id() ?>'>View Cart</a></p>
<?php
$Database = "L3TtL2B5DdY";
$Table = "tblProds";
if (isset($_SESSION['curCart']))
$Cart = unserialize($_SESSION['curCart']);
else
{
if (class_exists("shoppingCart"))
{
$Cart = new shoppingCart();
$Cart->setDatabase($Database);
echo ("<p>If statement ran successfully</p>");
}
else
exit("<p>The shoppingCart class is not available!");
}
$Cart->setTable($Table);
$Cart->getProductList();
$_SESSION['curCart'] = serialize($Cart);
?>
<p><a href='<?php echo "showCart.php?PHPSESSID=" . session_id() ?>'>View Cart</a></p>
</body>
</html>
Here is the relevant code on the "shoppingCart.php" page:
<?php
class shoppingCart
{
private $dbConn = "";
private $dbName = "";
private $tableName = "";
private $orders = array();
private $orderTable = array();
function _construct()
{
$this->dbConn = #new mysqli("localhost", "root", "");
if (mysqli_connect_errno())
die("<p>Unable to connect to the database server.</p>" . "<p>Error Code " .
mysqli_connect_errno() . ": " . mysqli_connect_error() . "</p>");
}
public function setDatabase($Database)
{
$this->dbName = $Database;
#$this->dbConn->select_db($this->dbName)
Or die("<p>Unable to select the database.</p>" . "<p>Error code " . mysqli_errno($this->dbConn) .
": " . mysqli_error($this->dbConn) . "</p>");
}
public function setTable($Table)
{
$this->tableName = $Table;
}
public function getProductList()
{
$sqlString = "SELECT prodID, prodName, prodPrice FROM $this->tableName";
#$qryResult = $this->dbConn->query($sqlString)
Or die("<p>Unable to perform the query.</p>" . "<p>Error code " . mysqli_errno($this->dbConn) .
": " . mysqli_error($this->dbConn) . "</p>");
echo "<table width='100%' border='1'>";
echo "<tr><th>Product ID</th><th>Product Name</th><th>Product Price</th><th>Select Item</th></tr>";
$row = $qryResult->fetch_row();
do
{
echo "<tr><td>{$row[0]}</td>";
echo "<td>{$row[1]}</td>";
echo "<td>{$row[2]}</td>";
echo "<td><a href='showCart.php?PHPSESSID=" . session_id() . "&operation=addItem&productID=" . $row[0] .
"'>Add</a></td></tr>";
$row = $qryResult->fetch_row();
} while ($row);
echo "</table>";
}
......
?>
When I try to load the main page it will display the two lines and that is all. I debugged all the errors when I first created the code and thought it would work. When I wrote the original version of this page I put the "connection" code on the same page and the table displayed fine, so I don't know what else it could be.
I installed WAMP on my Windows XP box and it seems to work fine. I haven't touched the configuration files for any of the programs and all my other test code seems to work fine. It is just when I try to contact an external file.
Any help would be greatly appreciated as I think my brain is turning to mush.
Thanks
You probably need to include the ShoppingCart.php file in your main page, so it has the definition of the ShoppingCart class. Try putting at the top of your main page:
<?php require('ShoppingCart.php'); ?>
What I think might be happening is that the cart object is getting unserialised from the Session, but there is no class definition, so it becomes an instance of an incomplete class. When you then call a method on it you are getting a fatal error. What probably doesn't help is that you may not be displaying errors, so the script will just end. You could also try putting at the top of the main page:
<?php ini_set('display_errors', true); ?>
This should make PHP errors get shown.
Edit
It might be worth pointing out that you can't store a database connection in the session. You need to connect to the server / select the database etc. on every request. I don't think your script is currently doing that.
Also, you can store objects in the session without worrying about the serialisation yourself, here is a quick example:
<?php
//include class definition before starting session.
require('ShoppingCart.php');
session_start();
if (!isset($session['cart'])) {
$session['cart'] = new ShoppingCart();
}
$cart = $session['cart'];
//do stuff to cart
$cart->doSomething();
//changes are now saved back to the session when the script is terminated, without you having to do anything.
You need to
include_once("ShoppingCart.php");
Read up on the different ways to include files
http://www.w3schools.com/PHP/php_includes.asp

Categories