Okay, I've narrowed this down to one key function.
It seems impossible, but every time I've "echo"ed it, this function always says that the variable array I'm using to store my data is no longer an array.
Offending Code
private function do_display_message_details()
{
$m_message_values = '';
$m_address = APP_ROOT_PATH;
if ($this->c_arr_stored_message_data)
{
echo "I AM AN ARRAY";
}
else
{
echo "I AM NOT AN ARRAY";
}
$m_message_name = $this->c_arr_stored_message_data['message-name'];
$m_arr_stored_message_data = $this->c_arr_stored_message_data['message-retrieved-data'];
foreach((array)$m_arr_stored_message_data as $m_message_value)
{
$m_message_row = explode(',', $m_message_value);
$m_message_values .= '<tr>';
$m_message_values .= '<td>' . $m_message_row[0] . '</td>';
$m_message_values .= '<td>' . $m_message_row[1] . '</td>';
$m_message_values .= '<td>' . $m_message_row[2] . '</td>';
$m_message_values .= '</tr>';
}
$this->c_html_page_content = <<< VIEWSTOREDMESSAGEDATA
<div id="lg-form-container">
<h2>Message name: $m_message_name</h3>
<h3>Message Data</h3>
<table border="1">
<tbody>
<tr>
<th>Date</th>
<th>Time</th>
<th>Message Values</th>
</tr>
$m_message_values
</tbody>
</table>
<br />
<form method="post" action="$m_address">
<label for="anothergo">Another Message?</label>
<button name="feature" value="display_message_data">Review Stored Message Data</button>
</form>
</div>
VIEWSTOREDMESSAGEDATA;
}
Constructor to show you it is set up as an array
private $c_arr_stored_message_data;
private $c_error_message;
private $c_page_content;
// ~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*
public function __construct()
{
$this->c_arr_stored_message_data = array();
$this->c_error_message = '';
$this->c_page_content = '';
}
But, if you try it on a different function, it works.
Trial Code That Works!
// ~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*
public function set_stored_message_data($p_arr_stored_message_data)
{
$this->c_arr_stored_message_data = $p_arr_stored_message_data;
if ($this->c_arr_stored_message_data)
{
echo "I AM AN ARRAY";
}
else
{
echo "I AM NOT AN ARRAY";
}
}
Your "I AM AN ARRAY" checks don't work quite as you think:
$x = array();
if ($x) {
echo 'I AM AN ARRAY';
} else {
echo 'I AM NOT AN ARRAY';
}
That prints out 'I AM NOT AN ARRAY', as an empty array evaluates to false in PHP. You can use var_dump to see exactly what content your variables have.
You have a variable named $c_page_content but later you refer to $c_html_page_content. Perhaps a mistake?
If the "messages" can contain user-supplied text, then there are XSS vulnerabilities in your code. It is essential to use htmlspecialchars to render text in HTML. For example, if $m_message_row[0] is text, you must write '<td>' . htmlspecialchars($m_message_row[0]) . '</td>'. Ditto for any other values that are not supposed to contain HTML markup that are written to HTML.
Your main issue, that the data is apparently not being stored in your c_arr_stored_message_data variable, is not possible to reproduce without seeing the connecting code that calls set_stored_message_data and do_display_message_details. All I can suggest is that you make sure you're calling them in the right order on the same instance of the same class.
Related
I have a function that creates a radio button in PHP:
// This function creates a radio button.
// The function takes two arguments: the value and the name.
// The function also makes the button "sticky".
function create_radio($value, $name = 'gallon_price')
{
// Start the element:
echo '<input type="radio" name="' .
$name .'" value="' . $value . '"';
// Check for stickiness:
if (isset($_POST[$name]) && ($_POST[$name] == $value))
{
echo ' checked="checked"';
}
// Complete the element:
echo " /> $value ";
} // End of create_radio() function.
I then leave the PHP form to create an html form and call the function three times with values that represent three different gas prices.
<span class="input">
<?php
create_radio('3.00');
create_radio('3.50');
create_radio('4.00');
?>
</span>
I am wondering how I could change this code so it would be possible to get the same output and only make one call to the create_radio function.
Thanks!
function create_radio($value, $name = 'gallon_price')
{
$output = "";
if (is_array($value)) {
while (count($value) > 0) {
$arr_value = array_pop($value);
$output .= create_radio($arr_value);
}
} else {
// Start the element:
$output .= '<input type="radio" name="' .
$name .'" value="' . $value . '"';
// Check for stickiness:
if (isset($_POST[$name]) && ($_POST[$name] == $value))
{
$output .= ' checked="checked"';
}
// Complete the element:
$output .= " /> $value ";
}
return $output;
}
A quick bit of recursion will allow the function to work for arrays and non arrays. Note: in the html you will need to echo the call to create_radio not just call it.
you could make $value an array create_radio(array('3.00','3.50','4.00')); just loop inside the function:
function create_radio($value,$name = 'gallon_price'){
foreach($value as $v){
// Start the element:
$out. = '<input type="radio" name="'.$name.'" value="'.$v.'"';
// Check for stickiness:
if(isset($_POST[$name])&&($_POST[$name]==$v)){
$out .= ' checked="checked"';
}
// Complete the element:
$out .= " /> $v ";
}
return $out;
} // End of create_radio() function.
call it:
echo create_radio(array('3.00','3.50','4.00'));
it is usually better not to echo inside the function.
I have form, which builds a rather large output setup in various elements, based on how the form is filled out. I can post the whole code, but i think this makes it easier to understand, what I am trying to do.
Let's say I have form, with one input text field called 'notes'.
In this example, we pretend i have entered "Hello World!" in 'notes'.
When the form is posted, the value entered into 'notes' is echoed within some elements:
<?php
echo '<div class="bon" id="bon">';
if (empty($_POST['notes'])) {
// Echo nothing
} else {
echo '<div class="bonHr"></div>';
echo '<div class="bonField">';
echo '<span>' . nl2br($_POST['notes']) . '</span>';
echo '</div>';
}
echo '</div>';
?>
And that is fine. Now I want to store the value in mySQL - I know how to do that.
Problem is I want to store the value including the elements around it, into a mysql textfield.
So what I really want to store is everything the contains, in this case:
<div class="bon" id="bon">
<div class="bonHr"></div>
<div class="bonField">
<span>Hello World!</span>
</div>
</div>
How can I do this??
The reason why I need to do this, is that the output varies alot. So please help me to figure out how I can take a "dump" of the output, and throw it into mySQL...
Just store your output in variable show it and save in database.
<?php
$output = "";
$output .= '<div class="bon" id="bon">';
if (empty($_POST['notes'])) {
// Echo nothing
} else {
$output .= '<div class="bonHr"></div>';
$output .= '<div class="bonField">';
$output .= '<span>' . nl2br($_POST['notes']) . '</span>';
$output .= '</div>';
}
$output .= '</div>';
echo $output;
//Save output to database
?>
I'm totally baffled. My entire page code is below.
Originally, I had the include header.php, sidebar, topMenuBar, & mainContentShell at the top of the page, ran the first query after it, and then the second query, etc for the rest of the page. Everything worked. My first query was different though... I checked that the $_GET['stone'] number was greater than zero and less than the select max(StoneID), but I could still get errors if someone manually put in the StoneID for a stone that was deleted from inventory. I revised my $_GET validation plan, and moved it above the included files so the header() redirect would work properly. Now, my second query won't work, even though it is completely unchanged.
Var_dump($querySN) yields string(53) "select StoneName from stonetypes where StoneID = '1' " and var_dump($resultSN) yields NULL.
It states: error occurred at line 35 --- $resultSN = $db->query($querySN);
States several times: Couldn't fetch mysqli
States a number of times: Property access is not allowed yet
And states in conclusion: Call to a member function fetch_assoc() on a non-object on line 36---$rowSN = $resultSN->fetch_assoc();
Does anyone know what's going on here and how I can fix it? Page code follows. Thanks!!!
<?php
require('./inc/config.inc.php');
$stone = (INT)$_GET['stone'];
require(MYSQL1);
$queryCk = "select StoneID from stonetypes";
$resultCk = $db->query($queryCk);
$var = array();
while ($rowCk = $resultCk->fetch_assoc()){
$var[] = $rowCk['StoneID'];
}
if(!in_array($stone, $var)) {
header('Location: beadgallery.php?type=stones');
exit;
} else {
include('inc/header.inc.php');
include('inc/sidebar.inc.php');
include('inc/topMenuBar.inc.php');
include('inc/mainContentShell.inc.php');
?>
<div id="mainContent">
<div class="center">
<?php
$querySN = "select StoneName from stonetypes where StoneID = '$stone' ";
$resultSN = $db->query($querySN);
$rowSN = $resultSN->fetch_assoc();
echo '<table id="cartDisplayTable">';
echo '<tr>';
echo '<td colspan="2">';
echo '<table id="titleTable">';
echo '<tr>';
echo '<td id="stoneTitle">';
if (isset($rowSN['StoneName'])){
echo '<h2>'.ucwords($rowSN['StoneName']).'</h2>';}
echo '</td>';
echo '</tr>';
$query = "select * from organized_inventory2 where StoneID = '$stone' ";
$result = $db->query($query);
$num_beadItems = $result->num_rows;
$justused='abc';
for ($i=0; $i < $num_beadItems; $i++) {
$row = $result->fetch_assoc();
if (!isset($row['itmphoto'])) {
echo '</table>';
echo '</td>';
echo '</tr>';
echo '<tr><td colspan="2"><hr id="cartDivider"></td></tr>';
echo '<tr>';
echo '<td id="cartImgCell">';
echo '<img src="img/nophoto.gif">';
echo '</td>';
echo '<td id="cartInfoCell">';
echo '<table id="innerTable">';
include ('inc/stoneCartInfo.inc.php');
} elseif ($row['itmphoto'] == $justused) {
echo '<tr><td colspan="2"><hr id="itemDivider"></td></tr>';
include ('inc/stoneCartInfo.inc.php');
} else {
echo '</table>';
echo '</td>';
echo '</tr>'
;
echo '<tr><td colspan="2"><hr id="cartDivider"></td></tr>'
;
echo '<tr>';
echo '<td id="cartImgCell">';
echo '<img src="img/invent/'.$row['itmphoto'].'">';
$justused = $row['itmphoto'];
echo '</td>';
echo '<td id="cartInfoCell">';
echo '<table id="innerTable">';
include ('inc/stoneCartInfo.inc.php'); }
}
echo '</table>'
;
echo '</td>';
echo '</tr>'
;
echo '</table>'
;
}
$result->free();
unset($result);
$db->close();
?>
</div> <!-- div class="center" -->
</div> <!-- div id="mainContent" -->
Integers don't nee quotes around the value as in StoneID = '1', this shouldn't be a problem because MySQL should typecast.
You have not checked what "$result" contains, if it's boolean then the query failed and you need to see the output of mysqli_error.
I have referred to similar questions like this and have done exactly the same way as it should have been but no success. Hence I would appreciate if some one can help me with this
I have a file called view.php which calls a function from a class based on a switch case condition. This function displays the output on the page with few links. When clicked on the link it calls another function which sits in my first function. But obviously when I click my link, nothing happens. That's my code.
view.php
require_once(..'/functions.php');
$functions = new myfile_functions();
<form method="post" action="view.php"><div>
<p><select name="potentialareas" id="potentialareas">
<option style="font-weight:bold;" value="-1">Select an area to view </option>
<?php
foreach($accessareas as $accessarea){
echo "<option value='".$accessarea->id."'>".$accessarea->name. " - " . $accessarea->reporttype. "</option>";
}
?>
</select>
</p>
<p><input name="view" id="view" type="submit" value="View" title="view" /><br /></p>
</div></form>
<div style="border-top:1px dotted #ccc;"></div>
<?php
if(isset($_POST['view']))
{
$hierarchyid = $_POST['potentialareas'];
$reporttype = $DB->get_record_sql("some query");
switch($reporttype->reporttype)
{
case "D Report":
$functions->getDepartmentReport($hierarchyid);
break;
case "S Report":
$functions->getSectionReport($hierarchyid);
break;
case "A Report":
$functions->getAreaReport($hierarchyid);
break;
}
}
functions.php
class myfile_functions(){
function getDepartmentReport($departmentid)
{
global $USER, $CFG, $DB;
$dname = $DB->get_record_sql("some query");
$output = "<div id='actualreport'><p><b>" . $dname->name. " Department Report</b></p>";
$output .= "<p>Activities started: </p>";
$output .= "<p>Activities Completed: </p></div>";
$output .= "<div id='separator' style='border-top:1px dotted #ccc;'></div>";
$output .= "<div id='listofsections'><p><b><i>Select the following for a more detailed report.</i></b></p>";
$snames = $DB->get_records_sql('some query');
foreach($snames as $sname)
{$output .= "<p>" .$sname->name. " <a href='view.php?section=" .$sname->id. "' name='section'><i>view report</i></a></p>";
}
$output .= "</div>";
if(isset($_GET['section']))
{
$this->getSectionReport($_GET['section']);
}
echo $output;
}
function getSectionReport($sectionid)
{
global $USER, $CFG, $DB;
$sname = $DB->get_record_sql("some query");
$output = "<div id='actualreport'><p><b>" . $sname->name. " Report</b></p>";
$output .= "<p>Num Users: </p>";
$output .= "<p>Activities Completed: </p></div>";
$output .= "<div id='separator' style='border-top:1px dotted #ccc;'></div>";
$output .= "<div id='listofareas'><p><b><i>Select the following for a more detailed report.</i></b></p>";
$anames = $DB->get_records_sql('some query');
foreach($anames as $aname)
{$output .= "<p>" .$aname->name. " <a href='view.php?area=" .$aname->id. "' name='view' id='view'><i>view report</i></a></p>";
}
$output .= "</div>";
if(isset($_GET['area']))
{
$areaid = $_GET['area'];
$this->getAreaReport($areaid);
}
echo $output;
}
Similarly another function calling the above function, n so on.
function getAreaReport($id)
{ .. same content but calling another function...}
So when ever I click my view report link, I get the id appended id in my querystring, something like
http://mydomain.com/view.php?section=5
Ideally the contents of getSectionReport() should get printed but its not. Please point out what is it that I am doing wrong.
Thanks in advance.
What's your main method for displaying everything? At the moment you have three functions, all of which link to eachother in various ways, but it doesn't look as if you're instantiating anything first. The PHP is being fed a parameter in your URL, sure, but if a class isn't instantiated and a method declared, how does it know what you want it to do?
For myfile.php, maybe you should do something like:
class MyFile
{
public function other_function()
{
// Various stuff
return 'stuff';
}
public function other_other_function()
{
// Various other stuff
return 'other stuff';
}
public function page_view($file_id)
{
$var = $this->other_function($file_id);
return $this->other_other_function($var);
}
}
$class = new MyFile;
echo $class->page_view($_GET['id']);
If the two functions are part of a class (as your comment above hints), then the call should be written as
$this->getUserReport($id);
If you're accessing a sibling function inside the same class, use:
class ClassName
{
public function sibling_function()
{
return 'Hey bro!';
}
public function my_function()
{
return $this->sibling_function();
}
}
If not, use the standard:
public function my_function()
{
return sibling_function();
}
If you're still having trouble, make sure your class is properly instantiated. There's no point calling another function if you're not even instantiating the class first:
$obj = new ClassName;
echo $obj->my_function();
When I call regularDashboard(), it appends to the beginning of my view. In my view I'm calling $reg from inside a formatted style. So it shouldn't be echoing out at the beginning of the view... Any ideas as to why this is happening?
public function dcr() {
// pass all dashboard accesses through this function
$username = $this->session->userdata("username");
$query = $this->db->get_where('users', array('username' => $username));
$userType = $this->session->userdata('userType');
if ($userType == 'regular') {
foreach ($query->result() as $row) {
$data = array('reg' => $this->regularDashboard(), 'firstname' => $row->firstname);
$this->load->view('dashboard', $data);
} public function regularDashboard () {
$userid = $this->session->userdata('userid');
$results = $this->db->query("SELECT * FROM users");
foreach ($results->result() as $row) {
if($userid != $row->userid) {
echo $row->firstname . " " . $row->lastname;
echo "<form method='GET' action='processing/lib/process-send-friend-request.php?'>";
echo '<input name="accepted" type="submit" value="Send User Request" /><br />';
echo '<input name="AddedMessage" placeholder="Add a message?" type="textbox" />';
echo '<br>Select Friend Type: ' . '<br />Full: ';
echo '<input name="full_friend" type="checkbox"';
echo '<input type="hidden" name="id" value="' . $row->idusers . '" />';
echo '</form>';
echo "<br /><hr />";
} elseif ($userid == $row->userid) {
echo $row->firstname . " " . $row->lastname;
echo "<br />";
echo "You all are currently friends";
}
}
}
Views are buffered. When you echo something directly in a controller, it is sent before the buffer is flushed (therefore before the output containing the view is sent to the browser), that's why it appears before anything.
You shouldn't to this (sending a direct output/echoing something outside of views), you risk getting into troubles as soon as you use anything related to headers (redirect, cookies, CI's sessions...)
UPDATE:
To fix it, just assign all those string to a variable (as jeff showed), and send that to the view:
$data['form'] = $row->firstname . " " . $row->lastname;
$data['form'] .= "<form method='GET' action='processing/lib/process-send-friend-request.php?'>";
$this->load->view('formview',$data);
There, you just echo $form and you'll have all your strings output correctly.
EDIT :
all above if you're inside a Controller. If you're in a Model, just assign everything to a variable and return it to the Controller:
function regularDashboard()
{
$form = $row->firstname . " " . $row->lastname;
$form .= "<form method='GET' action='processing/lib/process-send-friend-request.php?'>";
return $form;
}
In the controller:
$data['form'] = $this->model->regularDashboard();
$this->load->view('formview',$data);
If you allow me, I'd suggest writing the form directly into the view, without the hassle (and the structural error) of creating something that's supposed to be "presentation" outdside of views.
It seems that your issue is the use of echo from within regularDashboard(). Try setting a variable that contains the form markup and return it instead of using echo.
Here is an example:
function regularDashboard()
{
$html = "";
$html .= "<form>";
//Append the rest of the form markup here
return $html;
}