(EDITED QUES) PHP - Call function within another function - php

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();

Related

Error code "Invalid argument supplied for foreach()" when using json_encode (oop, php)

I'm trying to create a to do list. When creating new posts it should encode the information to json and put the information in a json array. But somehow it seems the information isn't encoded correctly and when trying to print the posts I get the error message "Invalid argument supplied for foreach()". I just can't find where the mistake is.
I'm fairly new at this so to complex answers might be to hard for me to understand.
Edit:
Adding the whole freaking code. Something is seriously wrong. 🤦‍♀️
index:
<?php
spl_autoload_register(function ($class) {
include $class . '.class.php';
});
$allPosts = new Lista;
if(isset($_REQUEST['addNewPost'])){
$allPosts->addNewPost($_REQUEST['ett'], $_REQUEST['tva'], $_REQUEST['tre']);
}
?>
<?php $page_title = "Att göra lista";
include("includes/header.php");
?>
<?php
include("includes/sidebar.php");
?>
<h2>Min att göra lista</h2>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
Uppgift: <input type="text" name="ett"/><br/>
Utfarare: <input type="text" name="tva"/><br/>
Senast: <input type="text" name="tre"/><br/>
<input type="submit" name="addNewPost" value="Lägg till post"/>
</form>
<?php
//Loopa igenom array
foreach ($allPosts->getTheList() as $key=>$val) {
echo "<section id='postPart'>" . $val->getEtt() . "<br/>" . $val->getTva(). " " . $val->getTre(). "</section><section id='buttonPart'><button type='button' name='klar'>Avklarad!</button> <button type='button' name='deletePost'>Ta bort</button>\n";
}
//echo "<section id='postPart'>" . $_REQUEST['one'] . "<br/>" . $_REQUEST['two'] . " " . $_REQUEST['three'] . "</section><section id='buttonPart'><button type='button' name='klar'>Avklarad!</button> <button type='button' name='deletePost'>Ta bort</button>\n";
var_dump($allPosts);
?>
</body>
</html>
Class: Lista:
<?php
class Lista{
public $theList=[];
function __construct(){
if(file_exists("text.json")>0)
$this->theList = json_decode(file_get_contents('text.json'), true);
}
function addNewPost($ett, $tva, $tre){
$posten = new Post ($ett, $tva, $tre);
array_push ($this->theList, $posten);
$jsonStr = json_encode($this->theList);
file_put_contents("text.json", $jsonStr);
}
function getTheList( ){
return $this->theList;
}
}
Class Post:
<?php
class Post{
public $ett;
public $tva;
public $tre;
function __construct ($ett, $tva, $tre){
$this->ett = $ett;
$this->tva = $tva;
$this->tre = $tre;
}
function getEtt():string{
return $this->ett;
}
function getTva(){
return $this->tva;
}
function getTre(){
return $this->tre;
}
}
Besides the typo, to json_encode an array of objects your need to make an exporter method which returns an array of each property or implement JsonSerializable
<?php
class Post implements JsonSerializable {
protected $whatIs = ' ';
protected $whoIs = ' ';
protected $whenIs = ' ';
function __construct($what,$who,$when){
$this->whatIs=$what;
$this->whoIs=$who;
$this->whenIs=$when;
}
public function jsonSerialize()
{
return get_object_vars($this);
}
}
$arr = [];
$arr[] = new Post(1,2,3);
echo json_encode($arr);
Result:
[{"whatIs":1,"whoIs":2,"whenIs":3}]
I think your problem is on this line:
$jsonStr = json_encode($this->$thePost, JSON_PRETTY_PRINT);
You might be trying to do this :
$jsonStr = json_encode($thePost, JSON_PRETTY_PRINT);
Since $thePost is an object, and not a property of your class. It could work if $thePost is a string that match a property name.

Other way of displaying image, when only having the link from php

I am making a tool to convert steam profile urls to the different steam ids, whatever.
I have the different functions, triggered when submitting the URL of the profile with a form.
One of the function are, that it gets the avatar of the regarding steam profile.
Actually it gets the link of the image. What I can do is, echo an img element with the link, this wont give me any flexibility since I wont be really able to style etc that afterwards.
Now, the function of getting the avatar, is in the function of the submit form.
I tried just inserting the image URL into an img element.
<img src"<?php echo $avatar ?>">
Well, then I get a error message, saying "$avatar" is undefined, even though I defined it in my main php tags. I think that is due to the fact that it is done inside the form function, could be wrong though.
My main question now is, what could be a different approach to this? I need that in the form function because it should only be called then.
Maybe I just have to use the inconvenient way of echoing an img element every time.
Here is the actual code.
<form method="post">
<input type="text" name="profile_url">
<input type="submit" value="click" name="submit">
</form>
<div id="avatar-div" style="height:100px; width:100px;">
<img src="<?php echo $avatar; ?>">
</div>
the main php part
if(isset($_POST['submit']))
{
display();
}
function display() {
require_once 'steamid.class.php';
$input = $_POST["profile_url"];
$api_key = "xxxxxxxxxxxxxxx";
$id = new SteamID($input,$api_key);
if(substr_count($input, ' ') === strlen($input)) {
echo "Enter URL";
} else {
if ($id->resolveVanity()) {
$avatar = $id->toAvatar();
$communityid = $id->toCommunityID();
echo $communityid . ", " . " ";
$steamid = $id->toSteamID();
echo $steamid . ", " . " ";
$userid = '[U:1:'.$id->toUserID().']';
echo $userid . ", " . " ";
} else {
echo "Profile wasnt found!";
}
}
}
I'm refactoring my answer based on the conversation we had. Here is the recommended PHP code.
function urlCheck() {
$input = $_POST["profile_url"];
if(empty($input)) {
echo "Enter URL";
return false;
} else {
return true;
}
}
function display() {
require_once 'steamid.class.php';
$api_key = "xxxxxxxxxxxxxxx";
$id = new SteamID($input,$api_key);
if (urlCheck()) {
if ($id->resolveVanity()) {
$communityid = $id->toCommunityID();
echo $communityid . ", " . " ";
$steamid = $id->toSteamID();
echo $steamid . ", " . " ";
$userid = '[U:1:'.$id->toUserID().']';
echo $userid . ", " . " ";
return $id->toAvatar();
} else {
echo "Profile wasn't found!";
}
}
}
You haven't mentioned where you're running display(), or where you're expecting the output (echo) to display. I can only assume you want it at the top of the page. Let me explain how to use this.
<head>
$avatar = display();
</head>
<body>
<div id="avatar-div" style="height:100px; width:100px;">
<img src="<?= $avatar ?>">
</div>
</body>
Basically the way this works, is that wherever you run display(), is where the echoes will output (in this case, before the body). Wherever you echo $avatar is where the id will be displayed. I hope this works for you.
Take a look at PHP's Variable Scope
Any variable used inside a function is by default limited to the local function scope.
To fix this problem, use the global keyword. This way you will explicitly set $avatar; as a global variable so it can be used outside of your display() function.
Here is how it would work for your example:
function display() {
global $avatar;
// Rest of your display() function
// Set $avatar somewhere in here
}
display(); // Actually call display so $avatar is set
<div id="avatar-div" style="height:100px; width:100px;">
<img src="<?=$avatar;?>">
</div>

My PHP array somehow doesn't see my array as an array

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.

Displaying HTML based on the selection

I'm doing this PHP tutorial on OOP and I'm trying to incorporate the procedural code from the essential training into it, to see if I actually learned anything beyond the basics, and I got stuck, big time.
So, I have these two functions inside the class I named Blog:
public function navigation($selected_subject, $selected_page) {
$output = "<ul class=\"subjects\" id=\"accordion\">";
$subject_set = $this->get_all_subjects($public);
while ($subject = mysqli_fetch_array($subject_set)) {
$output .= "<li";
if ($subject["id"] == $selected_subject['id']) { $output .= " class=\"blogselected\""; }
$output .= ">{$subject["menu_name"]}</li>";
$page_set = $this->get_pages_for_subject($subject["id"], $public);
$output .= "<ul class=\"pages\">";
while ($page = mysqli_fetch_array($page_set)) {
$output .= "<li";
if ($page['id'] == $selected_page['id'] ) { $output .= " class=\"blogselected\""; }
$output .= "><a href=\"../public/blog_index.php?page=" . urlencode($page["id"]) .
"\">{$page["menu_name"]}</a></li>";
}
$output .= "</ul>";
}
$output .= "</ul>";
return $output;
}
public function blog_page($selected_page){
if ($selected_page) {
echo "<h2>" . $selected_page['menu_name'] . "</h2>";
echo "<div class=\"page-content\">";
echo $selected_page['content'];
echo "</div>";
} else {
echo "<h2>Welcome to Widget Corp</h2>";
}
}
and this piece of code on the index page:
<?php
$blog = new Blog;
global $selected_page;
global $selected_subject;
?>
<div class="blog">
<div class="blogpost">
<?php echo $blog->blog_page($selected_page); ?>
</div>
<div class="blognav">
<?php echo $blog->navigation($selected_subject, $selected_page); ?>
</div>
</div>
The code partially works. The navigation with subjects and sub-pages gets displayed fine, when the links are clicked the id "?page=1" is passed to the url, but the problem is that the code is not adding a class "blogselected" to the active links, and it also does not display the content when the links are clicked. The only thing that gets displayed in the content area is the h2 "Welcome to Widget Corp" from else condition in the second function, so I believe the variables $selected_subject and $selected_page might be causing the problem, but I just can't figure it out on my own. I spent countless hours trying to solve this and I'm on the brink of giving up completely. What exactly am I missing here?

How to return the data of an iterate function in codeigniter

i wrote some code in codeigniter
index controller using model 'navigation':
$this->load->model('navigation');
$data['template']=$this->navigation->nav_template();
the nav_template() function generate string that will be output in brower:
function nav_template($uplevel=0)
{
$tablename=$this->db->dbprefix("test");
$sql="select * from $tablename where id_parent=$uplevel "
$menu_item=$this->db->query($sql);
foreach($menu_item->result_array() as $row)
{
if($something)
{
if
{
echo 'some str';
}
self::nav_template($uplevel);//call self
}
else
{
echo 'other str';
}
}
echo '</ul>';
}
in view file i am using an <?php echo $template ?>
but as we all known , i am using echo() to output string. i wanted to store the string in some php varialbe that can be used in view file template tag.
and the nav_template() function just called itself using self php keyword.
nowhere to define the var like this:
$template=''; and no where to return the string?
so , can anyone tell me how to return the output string within the nav_template() instead of echo it directly to browser?
ps: the output data is the formatted html code that will generate a treeview with help of some javascript scripts.
function nav_template($uplevel=0)
{
$tablename=$this->db->dbprefix("test");
$sql="select * from $tablename where id_parent=$uplevel "
$menu_item=$this->db->query($sql);
$out = "";
foreach($menu_item->result_array() as $row)
{
if($something)
{
$out .= self::nav_template($uplevel);
}
else
{
$out .= 'other str';
}
}
$out.= '</ul>';
return $out;
}

Categories