if else if condition not working properly - php

Test.php
<?php
$a = 'D:/mydomain/Slim/Lib/Table.php';
$b = '\Slim\Lib\Table';
foreach (array($a, $b) as $value)
{
if (file_exists($value))
{
echo "file_exist";
include_once($value);
new Table();
}
else if (class_exists($value))
{
echo "class_exist";
$class = new $value();
}
else
{
echo "error";
}
}
?>
and D:/mydomain/Slim/Lib/Table.php
<?php
class Table {
function hello()
{
echo "test";
}
function justTest()
{
echo "just test";
}
}
?>
When im execute test.php in browser the output result is:
file_exist
Fatal error: Cannot redeclare class Table in D:/mydomain/Slim/Lib/Table.php on line 2
if statement for class_exist is not trigger. namespace \Slim\Lib\Table is never exist.

The second, optional, parameter of class_exists is bool $autoload = true, so it tries to autoload this class. Try to change this call to class_exists( $value, false) See the manual.

The first if can be changed to:
if(!class_exists($value) && file_exists($file)
actually there are other problems:
$a = 'D:/mydomain/Slim/Lib/Table.php';
$b = 'Table'; //Since you don't have a namespace in the Table class...
//This ensures that the class and table are a pair and not checked twice
foreach (array($a=>$b) as $file=>$value)
{
if (!class_exists($value) && file_exists($file))
{
echo "file_exist";
include_once($file);
$class = new $value();
}
else if (class_exists($value))
{
echo "class_exist";
$class = new $value();
}
else
{
echo "error";
}
}

Related

PHP: pass global variable to finction?

There is code:
<?php
$pamiClient = new PamiClient($options);
$pamiClient->open();
$temp = 42;
$pamiClient->registerEventListener(
function (EventMessage $event )
{
if ($event instanceof VarSetEvent) {
if ($varName == 'CALLID') {
$temp = 43;
echo "Temp from CALLID: " , $temp, "\n";
}
if ($varName == 'BRIDGEPEER') {
echo "Temp from BRIDGPEER: " , $temp, "\n";
}
}
}
);
while(true) {
$pamiClient->process();
usleep(1000);
}
$pamiClient->close();
?>
How to pass $temp to function (EventMessage $event), so changes are made in
if ($varName == 'CALLID'){} -section may be seen in if ($varName == 'BRIDGEPEER') {} section ?
You can inherit variables from the parent scope with use, for example:
function (EventMessage $event ) use ($temp)
{
// to do something
}
Use global.
For example:
<?php
$varName = "foo";
function test() {
global $varName;
if ($varName == "foo") { ... }
}
Read more: https://www.php.net/manual/en/language.variables.scope.php

PHP class_exists - getting Fatal error: Cannot redeclare clas instead?

I want to return an error message when two classes provided by the user/ developer don't exist.
core/model/Conan.php,
namespace core\model;
class Conan
{
var $bodyBuild = 'extremely muscular';
var $birthDate = 'before history';
var $skill = 'fighting';
public function methodConan()
{
return 'The methodConan from namespace core\model';
}
}
local/model/Conan.php,
namespace local\model;
class Conan
{
var $bodyBuild = 'very skinny';
var $birthDate = '1963';
var $skill = 'comedy';
public function methodConan()
{
return 'The methodConan from namespace local\model';
}
}
index.php,
define ('WEBSITE_DOCROOT', str_replace('\\', '/', dirname(__FILE__)).'/');
include 'core/helper/BaseClassAutoloader.php';
// Autoload the core & local classes.
$autoloader = new BaseClassAutoloader([
'local/model/',
'core/model/'
]);
if (class_exists('\foo\model\Conan'))
{
echo 'from local';
}
else
{
if(class_exists('\boo\model\Conan'))
{
echo 'from core';
}
else
{
echo 'both don\'t exist';
}
}
I suppose to get 'both don\'t exist' as the result, I get this error instead,
Fatal error: Cannot redeclare class local\model\Conan in
C:\wamp\www...\local\model\Conan.php
on line 8
It doesn't really make sense!
Is it something wrong with my autoload below??
autoload class,
class BaseClassAutoloader
{
public function __construct($directory)
{
$this->directory = $directory;
spl_autoload_register(array($this,'getClass'));
}
private function getClass($class_name)
{
if(is_array($this->directory)): $mainDirectories = $this->directory;
else: $mainDirectories = array($this->directory); endif;
$subDirectories = [];
$namespace = "\\";
$isNamespace = false;
$parts = explode($namespace, $class_name);
if(strpos($class_name, $namespace) !== false)
{
$isNamespace = true;
}
$fileNameName = end($parts).'.php';
foreach($mainDirectories as $pathDirectory)
{
$iterator = new RecursiveIteratorIterator
(
new RecursiveDirectoryIterator(WEBSITE_DOCROOT.$pathDirectory), // Must use absolute path to get the files when ajax is used.
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($iterator as $fileObject)
{
if ($fileObject->isDir())
{
$pathnameReplace = str_replace('\\', '/', $fileObject->getPathname());
$array = explode("/",$pathnameReplace);
$folder = end($array);
if($folder === '.' || $folder === '..') {continue;}
$subDirectories[] = preg_replace('~.*?(?=core|local)~i', '', str_replace('\\', '/', $fileObject->getPathname())) .'/';
}
}
}
$merged_directories = array_merge($mainDirectories,$subDirectories);
foreach($merged_directories as $pathDirectory)
{
if(file_exists(WEBSITE_DOCROOT.$pathDirectory.$fileNameName))
{
include WEBSITE_DOCROOT.$pathDirectory.$fileNameName;
if($isNamespace === false) if (class_exists($class_name)) break;
}
}
}
}
try using require_once instead of include
try using include_once instead of include at line 62 oh BaseClassAutoLoader.php.
For future googlers, If you don't control the files inclusion process like say inside a framework, and you need an urget fix you can just wrap the class definition inside a check, and it will prevent php from throwing the above error.
if (!class_exists('AwesomCLass')) {
class AwesomCLass extends ParentClass {
// Do awesome stuff here all day long
}
}
For those who are getting fatal error while using class_exists can use a alternative , i found it useful.
$classname = 'Myclass';
if( class_exists( $classname ) ) {
echo "class exists";
} else {
echo "class not exists";
}
instead, we can use as given below
$classname = 'Myclass';
if( in_array($classname, get_declared_classes() ) ) {
echo "class exists";
} else {
echo "class not exists";
}

Is there any possibility to break a loop while calling a function?

Let's say I have a simple code:
while(1) {
myend();
}
function myend() {
echo rand(0,10);
echo "<br>";
if(rand(0,10) < 3) break;
}
This will not work with error code 'Fatal error: Cannot break/continue 1 level on line'.
So is there any possibility to terminate the loop during a subfunctin execution?
Make the loop condition depend upon the return value of the function:
$continue = true;
while( $continue) {
$continue = myend();
}
Then, change your function to be something like:
function myend() {
echo rand(0,10);
echo "<br>";
return (rand(0,10) < 3) ? false : true;
}
There isn't. Not should there be; if your function is called somewhere where you're not in a loop, your code will stop dead. In the example above, your calling code should check the return of the function and then decide whether to stop looping itself. For example:
while(1) {
if (myend())
break;
}
function myend() {
echo rand(0,10);
echo "<br>";
return rand(0,10) < 3;
}
Use:
$cond = true;
while($cond) {
$cond = myend();
}
function myend() {
echo rand(0,10);
echo "<br>";
if(rand(0,10) < 3) return false;
}

call to undefined function msg()

i m getting an error in the php code..
Fatal error: Call to undefined function msg()
but the function is already defined in the code here
whenever i click on a login button this login script runs
<?php
mysql_select_db("elunika", $con);
$a = $_POST['em'];
$b = $_POST['pwd'];
$c = $_POST['log'];
$b = md5($b);
if (isset($c)) {
$q = mysql_query("select * from registeration where email='$a' and password='$b'");
$r = mysql_num_rows($q);
if ($r) {
$_SESSION["Authenticated"] = 1;
$_SESSION['id'] = $a;
}
else {
$_SESSION["Authenticated"] = 0;
}
if ($_SESSION["Authenticated"] === 0) {
die(msg(0, "Incorrect Information"));
}
else {
session_write_close();
echo msg(1, "profile.php");
}
function msg($status, $txt)
{
return '{"status":' . $status . ',"txt":"' . $txt . '"}';
}
}
?>
Only unscoped functions are defined at compile-time (prior to execution). Your msg function however is just going to be defined if the if branch (the if (isset(…)) on line 9) is entered; so it's only going to be defined at the moment where the executor reaches it.
But in your code msg() is already called before the function declaration was encountered at run-time. Moving the function declaration up (= before the msg() call) should help:
function msg ($status, $txt) {
return '{"status":'.$status.',"txt":"'.$txt.'"}';
}
if($_SESSION["Authenticated"] === 0) {
die(msg(0,"Incorrect Information"));
} else {
session_write_close();
echo msg(1,"profile.php");
}

PHP Namespace and Include() with classes

there is a project which I need to extend. All classes are in seperate files, I need to extend some of the classes without rewriting existing code in other files. My idea was to use namespaces but I fail. Here is an example:
I've renamed the original A.php class file to A_Original.php:
class A
{
public function hello()
{
echo "hello world from Class A\n";
}
}
Then created a new A.php:
namespace AOriginal {
include 'A_Original.php';
}
namespace {
class A
{
public function hello()
{
echo "hello world from Class A Extended\n";
}
}
}
This fails because on including the original A_Original.php file the class is dumped to the global scope (thus ignoring the namespace command).
I can not modify the existing code inthe A_Original.php file, but renaming is ok.
The other project files (whic I cannot modify) use a require "A.php".
How to accomplish this?
You can extend a class without modifying its existing behaviour:
class A {
public function foo(){
}
}
class MySubClassOfA extends A {
public function bar(){
}
}
You can add your own methods to MySubClassOfA, i.e. bar(). You can call the foo method on MySubClassOfA and it's behaviour is the same, unless you define a method called foo in MySubClassOfA.
I guess that you have no choice but add the single line of "namespace xxx;" code on top of all your files. The following PHP CLI script may be useful.
<?php
function convert($namespace, $srcdir, $dstdir)
{
try
{
$files = glob("$srcdir/{*,.*}", GLOB_BRACE);
if ( ! file_exists($dstdir) && ! mkdir($dstdir) )
{
throw new Exception("Cannot create directory {$dstdir}");
}
if ( ! is_dir($dstdir) )
{
throw new Exception("{$dstdir} is not a directory");
}
foreach ( $files as $f )
{
extract(pathinfo($f)); // then we got $dirname, $basename, $filename, $extension
if ( $basename == '.' || $basename == '..' )
{
continue;
}
if ( is_dir($f) )
{
$d = $dstdir. substr($f, strlen($srcdir));
convert($namespace, $f, $d);
continue;
}
print "processing {$f} ... ";
if ( ($s = file_get_contents($f)) === FALSE )
{
throw new Exception("Error reading $f");
}
if ( preg_match("/^\s*namespace\s+\S+;/m", $s) )
{
print "already has namespace, skip";
}
else
{
$lines = preg_split("/(\n|\r\n)/", $s);
$output = array();
$matched = FALSE;
foreach ( $lines as $s )
{
$output[] = $s;
// check if this is a PHP code?
if ( ! $matched && preg_match('/<(\?(php )*|%)/', $s) )
{
$matched = TRUE;
print "insert namespace ... ";
$output[] = "namespace {$namespace};";
}
}
if ( file_put_contents("{$dstdir}/{$basename}" , implode("\n", $output)) === FALSE )
{
throw new Exception("Cannot save file {$dstdir}/{$basename}");
}
if ( ! $matched )
{
print ("not a PHP file, skip.");
}
else
{
print "done!";
}
}
print "\n";
}
}
catch (Exception $e)
{
print 'Error: '. $e->getMessage() .' ('. $e->getCode() .')' ."\n";
}
}
extract($_SERVER);
if ( $argc < 4 )
{
?>
Usage: php -F <?=$argv[0]?> <namespace> <source_dir(s)> <dst_dir>
Convert PHP code to be namespace-aware
<?
return;
}
else
{
for ( $i = 2; $i < $argc - 1; $i++ )
{
convert($argv[1], $argv[$i], $argv[$argc-1]);
}
}
?>
How about eval()?
New A.php
$lines = file('a_original.php');
array_unshift($lines, 'namespace AO;?>');
$string = implode(chr(13).chr(10), $lines);
eval($string);
class A extends AO\A
{
public function hello()
{
parent::hello();
echo "hello world from Class A Extended\n";
}
}

Categories