Php can't redeclare function - php

as far as I can tell the function is only declared once . but I get this error Cannot redeclare calcPercentages() and it tells me it was declared on line 17 which is correct
the function that contains the errant function...
function auditStats($audit){
$mysqli = dbConnect();
$audit_id = $audit;
$result = $mysqli->query("SELECT imageGrade, SUM(imageGrade=1) AS grade1, SUM(imageGrade=2) AS grade2, SUM(imageGrade=3) AS grade3, COUNT(*) AS total_imgs FROM image WHERE type != 'standard' and auditID ='$audit_id'")or exit("Error code ({$mysqli->errno}): {$mysqli->error}");
$row = $result->fetch_assoc();
$grade1 = $row['grade1'];
$grade2 = $row['grade2'];
$grade3 = $row['grade3'];
$totalImgs = $row['total_imgs'];
function calcPercentages($grade, $total){
$percent = round(($grade / $total) * 100,2);
return $percent;
}
if ($totalImgs != 0){
$percent_1 = calcPercentages($grade1, $totalImgs);
}
$return_array = [
'total'=>$totalImgs,
'percent_1'=>$percent_1
];
return $return_array;
}
The function isn't being called anywhere except within the auditStats function and the results are called further down the page using
$percent_1 = auditStats($auditID)[percent_1];
Please excuse me if I have made on obvious newbie error, I am moving from procedural to OOP and am just starting out with it.

You declare calcPercentages inside the auditStats function, so it gets re-declared every time you call auditStats.
Move calcPercentages outside of auditStats.

In PHP, unlike say JS, a function is never local to another function, so when the line function calcPercentages... is reached, you're creating a global function called calcPercentages. When it's run again, you're trying to create another global function with the same name, and you get the error.
Either move the declaration outside globally, put it in a class or object or make an anonymous function.

Related

Trying to run app from function and i have an error when i trying to call some variable inside some functinon

Maybe this is simple thing. But I'm so confused. What's going here.
So I had made function which one calling all others files from app.
load.php
function RunApp(){
$files = array(
'/dir/PdoConn.php',
'/dir/class.php',
'/dir/function.php',
'/dir/something.php',
'/dir/template.php',
...);
foreach ($files as $include){
$path = MAIN_DIR . $include;
file_exists($path) ? require_once $path : die();
}
}
Of course in the firsts files, are connection with DB, with PDO.
So in some of those files are some functions, classes etc.
So what's happening, if I try to use $conn(pdo object) variable in some function.
Let's say:
function.php
function GetArticle($id){
global $conn;
$article = $conn->prepare("SELECT * FROM article WHERE id = ?");
$article->execute([$id]);
return $article;
}
(this function is only example, so do not care about the SQL statement)
This will throw an error:
Uncaught Error: Call to a member function prepare()
But if I do in last required file (/dir/template.php)
print_r(get_defined_vars());
It will have this in array:
[conn] => PDO Object
Of course if I delete whole function RunApp() and include those files just from that foreach, everything work perfectly.
The files are being required inside your runapp() function. So any variables they assign will be local to that function, unless the variables are declared global.
So PdoConn.php need to have global $conn; in it. And all the other files need to declare any global variables they define.

Undefined Variable within class

I recently made a class in PHP
I am trying to declare a variable within class and using str_replace in a function but its show undefined variable
class Status{
$words = array(".com",".net",".co.uk",".tk","co.cc");
$replace = " ";
function getRoomName($roomlink)
{
echo str_replace($words,$replace,$roomlink);
}
}
$status = new Status;
echo $status->getRoomName("http://darsekarbala.com/azadari/");
Any kind of help would be appreciated thanks you
Your variables in the function getRoomname() aren't adressed properly. Your syntax assumes the variables are either declared within the function or passed while calling the function (which they aren't).
To do this within a class, do it while using $this->, like this:
function getRoomName($roomlink)
{
echo str_replace($this->words,$this->replace,$roomlink);
}
For further informations, please have a look into this page of the manual.
Maybe because of the version or something, when I tested your exact code, I got syntax error, unexpected '$words' (T_VARIABLE), expecting function (T_FUNCTION), so setting your variables to private or public should fix this one.
About the undefined varible, you have to use $this-> to access them from your class. Take a look:
class Status{
private $words = array(".com",".net",".co.uk",".tk","co.cc"); // changed
private $replace = " "; // changed
function getRoomName($roomlink){
echo str_replace($this->words, $this->replace, $roomlink); // changed
}
}
$status = new Status;
echo $status->getRoomName("http://darsekarbala.com/azadari/");
Also, since getRoomName isn't returning anything, echoing it doesn't do much. You could just:$status->getRoomName("http://darsekarbala.com/azadari/");.
or change to :
return str_replace($this->words, $this->replace, $roomlink);

What is correct syntax for calling a function recursively in php

I have a function which is using recursion to call itself and I need to know the correct syntax for calling itself.
Note: I am using Object oriented programming technique and the function is coming from a class file.
Below is my function
// Generate Unique Activation Code
//*********************************************************************************
public function generateUniqueActivationCode()
{
$mysql = new Mysql();
$string = new String();
$activation_code = $string->generateActivationCode();
// Is Activation Code Unique Check
$sql = "SELECT activation_id FROM ". TABLE_ACTIVATION_CODES ." WHERE activation_code='$activation_code' LIMIT 1";
$query = $mysql->query($sql);
if($mysql->rowCount($query) > 0)
{
// This function is calling itself recursively
return generateUniqueActivationCode(); // <- Is this syntax correct in Oops
}
else
{
return $activation_code;
}
}
Should the code to call it recursively be
return generateUniqueActivationCode();
OR
return $this->generateUniqueActivationCode();
or if something else other than these 2 ways.
Please let me know.
You would need to call it with the $this variable since your function is part of the instance. So:
return $this->generateUniqueActivationCode();
PS: Why not just try both methods and see if it generates any errors?
Recursion is the COMPLETELY WRONG WAY TO SOLVE THIS PROBLEM
Unlike iteration you're filling up the stack, and generating new objects needlessly.
The right way to solve the problem is to generate a random value within a scope which makes duplicates very unlikely, however without some external quantifier (such as a username) to define the scope then iteration is the way to go.
There are further issues with your code - really you should be adding records in the same place where you check for records.
I am using Object oriented programming technique and the function is coming from a class file
Then it's not a function, it's a method.
And your code is susceptibale to SQL injection.
A better solution would be:
class xxxx {
....
public function generateUniqueActivationCode($id)
{
if (!$this->mysql) $this->mysql = new Mysql();
if (!$this->string) $this->string = new String();
$limit=10;
do {
$activation_code = $string->generateActivationCode();
$ins=mysql_escape_string($activation_code);
$sql="INSERT INTO ". TABLE_ACTIVATION_CODES ." (activation_id, activation_code)"
. "VALUES ($id, '$ins)";
$query = $mysql->query($sql);
if (stristr($query->error(), 'duplicate')) {
continue;
}
return $query->error() ? false : $activation_code;
} while (limit--);
return false;
}
} // end class

Accessing array in class structure

I want to validate a form with php.
Therefor I created a class "benutzer" and a public function "benutzerEintragen" of this class to validate the form:
class benutzer
{
private $username = "";
private $mail = "";
private $mail_check = "";
private $passwort = "";
private $passwort_check = "";
public $error_blank = array();
public $error_notSelected = array();
public $error_notEqual = array();
public function benutzerEintragen () {
$textfields[0] = $this->username;
$textfields[1] = $this->mail;
$textfields[2] = $this->mail_check;
$textfields[3] = $this->passwort;
$textfields[4] = $this->passwort_check;
foreach ($textfields as $string) {
$result = checkFormular::emptyVariable($string);
$error_blank[] = $result;
}
In the function "benutzerEintragen" i filled the variables "username,mail" and so on with the appropriate $_POST entries (not shown in the code above). The call
checkFormular::emptyVariable($string)
just returns "TRUE" if the field is not set or empty otherwise FALSE.
Now when i try to create a new instance of this class, execute the function and get access to $error_blank[0] the array is empty!
if (($_SERVER['REQUEST_METHOD'] == 'POST')){
$BENUTZER = new benutzer();
$BENUTZER->benutzerEintragen();
echo $BENUTZER->error_blank[0];}
So the last line is leading to a "Notice: Undefined offset: 0". It seems to be related to the array structure, because if i do
echo $BENUTZER->mail;
I get any input I wrote in the form, which is correct. Also the foreach loop seems to do the right thing when i run the debugger in phpEd, but it seems like the array "error_blank" is erased after the function is executed.
Any help would be greatly appreciated. Thanks in advance.
There is a scope problem here. You do have a class attribute with the name. Unlike in Java where using a local variable with the same name as a class variable automatically selects the class attribute this is not the case in PHP.
Basically you are saving your output in a local variable which gets discarded once you leave the function. Change $error_blank[] = $result; to $this->error_blank[] = $result; and you should be fine.
First of all this seems overly complicated way to do a simple task, but that wasn't actually the question.
You are creating a new $error_blank variable that is only in function scope. If you wish to use the class variable you should use $this->error_blank[]

Yet another 'Call to a member function on a non-object' problem

I have a html page that calls a php object to get some data back from the database. It works fine, but the script was getting unwieldy so I decided to break some of it out into a bunch of functions.
So I have the following files:
// htdocs/map.php
<?php
include("config.php");
include("rmap.php");
$id = 1;
$gamenumber = getGameNumber($id);
echo $gamenumber;
?>
// htdocs/config.php
<?php
$_PATHS["base"] = dirname(dirname(__FILE__)) . "\\";
$_PATHS["includes"] = $_PATHS["base"] . "includes\\";
ini_set("include_path", "$_PATHS[includes]");
ini_set("display_errors", "1");
error_reporting(E_ALL);
include("prepend.php");
?>
// includes/prepend.php
<?php
include("session.php");
?>
// includes/session.php
<?php
includes("database.php");
class Session {
function Session() {
}
};
$session = new Session;
?>
// includes/database.php
<?php
include("constants.php");
class Database {
var $connection;
function Database() {
$this->connection = mysql_connect(DB_SERVER, DB_USER, DB_PASS) or die(mysql_error());
mysql_select_db(DB_NAME, $this->connection) or die(mysql_error());
}
function query($query) {
return mysql_query($query, $this->connection);
}
};
/* Create database connection */
$database = new Database;
?>
// includes/rmap.php
<?php
function getGameNumber($id) {
$query = "SELECT gamenumber FROM account_data WHERE usernum=$id";
$result = $database->query($query); // line 5
return mysql_result($result, 0);
}
?>
And constants has a bunch of defines in it (DB_USER, etc).
So, map.php includes config.php. That in turn includes prepend.php which includes session.php and that includes database.php. map.php also includes rmap.php which tries to use the database object.
The problem is I get a
Fatal error: Call to a member function on a non-object in
C:\Develop\map\includes\rmap.php on line 5
The usual cause of this is that the $database object isn't created/initialised, but if I add code to show which gets called when (via echo "DB connection created"; and echo "using DB connection";) they are called (or at least displayed) in the correct order.
If I add include("database.php") to rmap.php I get errors about redefining the stuff in constants.php. If I use require_once I get the same errors as before.
What am I doing wrong here?
$database is not in the scope of function GetGameNumber.
The easiest, though not necessarily best, solution is
<?php
function getGameNumber($id) {
global $database; // added this
$query = "SELECT gamenumber FROM account_data WHERE usernum=$id";
$result = $database->query($query); // line 5
return mysql_result($result, 0);
}
?>
global is deemed not perfect because it violates the principles of OOP, and is said to have some impact on performance because a global variable and all its members are added to the function's scope. I don't know how much that really affects performance, though.
If you want to get into the issue, I asked a question on how to organize such things a while back and got some good answers and links.
You need to include
global $database;
at the top of getGameNumber(), since $database is defined outside of getGameNumber itself
Your $database varibleis not accessible from the function's scope automatically. You might need to declare it as global $database; in the function.
Scopes in PHP are explained in the documentation: http://de3.php.net/manual/en/language.variables.scope.php
Please also mind that PHP 4and MySQL3 are out of support for a looooong time and might contain security problems and other unfixed issues.

Categories