How to check filename in if condition that calls function in php - php

i'm calling multiple functions from a function...as per my scope i want to call a specific function from parent function as per file that calls that function...
function dispcategories() {
include ('database/connection.php');
$select = mysqli_query($con, "SELECT * FROM categories");
while ($row = mysqli_fetch_assoc($select)) {
echo "<table class='category-table'>";
echo "<tr><td class='main-category' colspan='2'>".$row['category_title']."</td></tr>";
dispsubcategories($row['cat_id']);
dispsubcategoriesstate($row['cat_id']);
echo "</table>";
}
}
From dispcategories i want to call dispsubcategoriesstate() if and only if file updatestate.php calls dispcategories()...if any other file calls dispcategories() than it should not call to dispsubcategoriesstate()...
Hope everyone get the question it is possible to check file name threw if condition or not who calls the function

Including a file is just like typing it into your source code. You can use the magic constant __FILE__ to determine the current file, but this won't tell you what file the calling function was written in.
I'd suggest that you should rather pass a parameter to your function and then call the subroutine based on that.
Declare your function like this and replace the line dispsubcategoriesstate($row['cat_id']); with the block shown below
function dispcategories($fetchSubCategories = false) {
// your code goes here
if ($fetchSubCategories === true) {
dispsubcategoriesstate($row['cat_id']);
}
// the rest of your code goes here
}
When you call it from the file where you do not want sub-categories you will call it like you do now:
dispcategories();
Whenever you want it to fetch the subcategories you can pass the parameter through like this:
dispcategories(true);
I'm using an optional function argument and if this is confusing you should read the manual page.

Related

PHP declared variable, to another file that's included via function

I have some kind of problem, but i don't get it.. I have an function for including/requiring files, which check is file already included and does exists:
function __include($fileclass, $is_required=false) {
static $already_included = array();
// checking is set extension of php file, if not append it.
if (substr($fileclass,-4)!=".php") $fileclass = $fileclass.".php";
// if already included return;
if (isset($already_included[$fileclass])) return true;
// check if file exists:
if (file_exists($fileclass)) {
if (!$is_required) include $fileclass;
else require $fileclass;
$already_included[$fileclass] = 1;
return true;
}
else {
if ($is_required) die("can't find required file");
return false;
}
}
And it works good, but when i started to work on the project, i've used it to include a file, which uses variable from parent file (the one that included it), but it drops notice Notice: Undefined variable: VARIABLE_NAME.
So to be clear at coding:
I have two files file_parent.php and file_child.php, what I've tried:
file_parent.php:
function __include($fileclass, $is_required=false) { /** i've mentioned it above **/ }
class __CONNECTION {
private $test;
public function __construct() {
$this->test = "SOMETHING";
}
};
$Connect = new __CONNECTION();
// here i used it to include the children file:
__include('file_child.php');
file_child.php:
print_r($Connect);
And i get Notice: Undefined variable: Connect.
When i change at file_parent.php my function include:
__include('file_child.php');
to standard include:
include 'file_child.php';
Everything will work fine, variable is defined and will be printed.
I guess there's some problem with function, but could someone explain what's the real reason for happening this, and is there a possible repair to fix it to including/requiring works through function and to not lose variables from previous files.
Thanks!
Well, how do i see, when i printed all defined variables (get_defined_vars()), i got this:
Array
(
[fileclass] => test_file2.php
[is_required] =>
[already_included] => Array
(
)
)
So that means the variables are passed, but only one that exists within function (because the function is temporary), so i could make it work to pass variables to function, but as it's not the only variable I need so I am gonna use one of two way:
global as #Tom Doodler said in comment, and later catch it with $GLOBALS
or use function to do checks and return just a path if exists/or empty string if file doesn't exists and then just include/require it.
Thanks everyone.
I will not accept this answer, so if someone could better explain the way function behaves in this solution, i will accept that.

how to include script of variables in a class? undefined variable

got a script which has string variables that represent data fields like they are in the database. because this project is a complete mess this is a stage in cleaning it up and not having to rewrite the field name in numerous locations.
so one script 'DataKeys.php' will have variables set to field names.
//results from query1
$keyField1 = 'field1';
$keyField2 = 'field2';
these two vars above is only a snippet of a much longer list.
I want to access this file and use these vars when I am formatting the data to be more friendly for the front end. this script is being accessed in a class however the fields, $keyField1, defined in the script is not being found in the class. I did have the actual string there but I think single access point would be best so when I make future changes I don't need search the whole project.
class DataFormatter {
//put your code here
public function __construct() {
$documentRoot = filter_input(INPUT_SERVER, "DOCUMENT_ROOT");
include ($documentRoot . '/database/values/DataKeys.php');
}
public function cleanData($data){
if (is_null($data) || empty($data))
{
return;
}
foreach($data as $row){
$field1Value = $row[$keyField1];
unset($row[$keyField1]);
}
}
}
I also tried moving the include outside the class definition.
$documentRoot = filter_input(INPUT_SERVER, "DOCUMENT_ROOT");
include ($documentRoot . '/database/values/DataKeys.php');
The error that is being reported is :
Undefined variable: keyField1
SOULTION
Maybe not the optimal way but I took the include statement and placed it inside the function. The code above is just a demo of what I was trying to achieve not the actual code I am using.
the 2 variables are available just after the "include".
you can for example, put the 2 values in properties of the object
include ...;
$this->keyField1 = $keyField1;
$this->keyField2 = $keyField2;
You have to assign DataKeys.php to class member.
class DataFormatter {
private $keyField1;
private $keyField2;
public function __construct($filename) {
include $filename;
$this->keyField1 = $keyField1;
$this->keyField2 = $keyField2;
}
}
$dataFormatter = new DataFormatter(filter_input(INPUT_SERVER, 'DOCUMENT_ROOT') . '/database/values/DataKeys.php');

Calling php method from external function produces error

function KeepSamePage($text)
{
$sb_w = $oPdf->GetStringWidth($text);
$num_lines = explode("\n",$text);
$total = 0;
foreach($num_lines as $line)
{
$y = $oPdf->GetY();
$page_height = 11 * 25.4;
$this_width = $oPdf->GetStringWidth(strip_tags($line));
$extra_line = floor($this_width / $w);
$is_line = $this_width / ($w - 1);
$is_line = $this_width == 0 ? 1 + $extra_line : ceil($is_line) + $extra_line;
$total = $total + $is_line;
}
$sb_height = $total * 5;
if(($page_height - $y) < $sb_height){ $oPdf->AddPage(); }
}
KeepSamePage($signature_block);
I'm using FPDF and I'm creating a function to keep the signature page of a letter all on the same page. This checks to see if it would go to the next page and if soo, then it does an AddPage();
The issue I'm having is that when I don't have it in a function, it works perfectly, but when I put it within a function, I get errors when calling the methods in the class represented by $oPdf.
So, my question generally is this: Is it possible to have a regular function in PHP call a class method as I have below? If it is possible, what am I doing wrong?
ERROR GENERATED IS:
Fatal error: Call to a member function GetStringWidth() on a non-object in /home/jarodmo/public_html/cms/attorney_signature_block.php on line 18
Oh, and an explanation of my function just in case you're interested or someone else finds it.
Text has \n for new lines in it so the PDF will put the text of the signature block on the next line. Each new array element should be a new line, so I would need to multiply the number of lines by my line height, 5 in this case. (See $total * 5).
I check to see where we are on the page, find the difference between the page height and the Y position, then check that against the height of the signature block. If the signature block is bigger, then it wouldn't fit and I know we need a manual page break.
Also, because I do the explode with the \n to see the lines, I also have to check to make sure that none of the lines is still wider than the page otherwise it would word wrap and really be 2 lines (or more) where I was only counting it as 1 because it was just one array element. I know a signature block shouldn't have text wide enough to be on 2 lines, but I wrote this to be applicable for more than just signature blocks. I wanted to be able to call this function anywhere I wanted to make sure certain text stayed on the same page. Call the function, check the text I'm about to write to the PDF and move on knowing that the desired text would all be on the same page.
Thanks for all of the help and comments. SO is the best.
$oPdf
is not defined on your code. You need to define it, and maybe read PHP variable scope.
You are trying to access methods of the $oPdf object in your function, but your function has no idea what $oPdf is, thus, the error message.
you have to do something like this.
function KeepSamePage($text) {
$oPdf = new your_string_class();
$sb_w = $oPdf->GetStringWidth($text);
}
or
$oPdf = new your_string_class();
function KeepSamePage($text, $oPdf) {
$sb_w = $oPdf->GetStringWidth($text);
}
Try the following:
function KeepSamePage($text) {
global $oPdf;
…
}
The problem is, that the object is defined outside your function and you will have to allow your function to access it.
// Edit:
If you want to avoid global for whatever reason, you will have to pass your object to the function like this:
function KeepSamePage($text, $oPdf) {
…
// IMPORTANT! $oPdf has changed in this function, so you will have to give it back
return $oPdf;
}
You can call your function like this:
$oPdf = KeepSamePage($signature_block, $oPdf);
The advantage is, that you see in the main thread, that your function might has changed the object.
// Edit 2: I think, I was wrong on the edit1 in your case. As you pass the complete object to the function every change does apply to the object, so the changes will still be existant without giving back the result. If this was a variable that was defined in the main thread, you would have to give back the new value:
$a = 1;
function result1($a) {
++$a;
}
function result2($a) {
return ++$a;
}
echo $a."\n"; // 1
result1($a);
echo $a."\n"; // 1
$a = result2($a);
echo $a."\n"; // 2

Can't call an object method. PHP reports variable undefined

This is the weirdest bug! It is probably something silly, but I have no idea how to fix it. If anyone could help, I would be most grateful! I have three files, one is called items.php, another is called tableFunctions.php, and the third is called mysql.php. I use two global objects called 'mysql' and 'tableFunctions'. They are stored in the files 'mysql.php', and
'tableFunctions.php', respectively. In each file, I create an instance of its object, assigning it to the global variable $_mysql, or $_table. like this:
In the file mysql.php:
global $_mysql;
$_mysql = new mysql();
In the file tableFunctions.php:
global $_table;
$_table = new tableFunctions();
Here's how it is supposed to work:
The items.php file includes the tableFunctions.php file...
Which in turn, needs the mysql.php file, so it includes it too.
In the items.php file, I call the method getTable(), which is contained in the object tableFunctions.(and in the variable $_table.) Like this:
$t = $_table->getTable('items');
The getTable function calls the method, arrayFromResult(), which is contained within in the object mysql.(and in the variable $_mysql.) Like this:
$result = $_mysql->arrayFromResult($r);
That's where I get the error. PHP says that the variable '$_mysql' is undefined, but I defined it in the 'mysql.php' file.(see above) I also included mysql.php with the following code:
include_once 'mysql.php';
I have no idea what is wrong! If anyone can help that would be much appreciated.
The source files can be downloaded with the following link: https://www.dropbox.com/sh/bjj2gyjsybym89r/YLxqyNvQdn
That's a common mistake, in the place of definition you need only the line:
$_mysql = new mysql();
and when you want to use it inside a function, only there you have to declare it as a global variable (otherwise it is considered like any other function variable):
global $_mysql;
so, for example, if we'll take your method:
function getTable($tableName) {
$r = mysql_query("SELECT * FROM $tableName");
err($r, 'mysql returned null when getting table!');
$result = $_mysql->arrayFromResult($r);
return $result;
}
it should be changed to:
function getTable($tableName) {
global $_mysql;
$r = mysql_query("SELECT * FROM $tableName");
err($r, 'mysql returned null when getting table!');
$result = $_mysql->arrayFromResult($r);
return $result;
}

How to pass parameters to PHP template rendered with 'include'?

need your help with PHP templating. I'm new to PHP (I'm coming from Perl+Embperl). Anyway, my problem is simple:
I have a small template to render some item, let it be a blog post.
The only way i know to use this template is to use 'include' directive.
I want to call this template inside a loop going thru all the relevant blog posts.
Problem: I need to pass a parameter(s) to this template; in this case reference to array representing a blog post.
Code looks something like this:
$rows = execute("select * from blogs where date='$date' order by date DESC");
foreach ($rows as $row){
print render("/templates/blog_entry.php", $row);
}
function render($template, $param){
ob_start();
include($template);//How to pass $param to it? It needs that $row to render blog entry!
$ret = ob_get_contents();
ob_end_clean();
return $ret;
}
Any ideas how to accomplish this? I'm really stumped :) Is there any other way to render a template?
Consider including a PHP file as if you were copy-pasting the code from the include into the position where the include-statement stands. This means that you inherit the current scope.
So, in your case, $param is already available in the given template.
$param should be already available inside the template. When you include() a file it should have the same scope as where it was included.
from http://php.net/manual/en/function.include.php
When a file is included, the code it
contains inherits the variable scope
of the line on which the include
occurs. Any variables available at
that line in the calling file will be
available within the called file, from
that point forward. However, all
functions and classes defined in the
included file have the global scope.
You could also do something like:
print render("/templates/blog_entry.php", array('row'=>$row));
function render($template, $param){
ob_start();
//extract everything in param into the current scope
extract($param, EXTR_SKIP);
include($template);
//etc.
Then $row would be available, but still called $row.
I use the following helper functions when I work on simple websites:
function function_get_output($fn)
{
$args = func_get_args();unset($args[0]);
ob_start();
call_user_func_array($fn, $args);
$output = ob_get_contents();
ob_end_clean();
return $output;
}
function display($template, $params = array())
{
extract($params);
include $template;
}
function render($template, $params = array())
{
return function_get_output('display', $template, $params);
}
display will output the template to the screen directly. render will return it as a string. It makes use of ob_get_contents to return the printed output of a function.

Categories