this is my first question here and i hope you can help me ..
I am trying to find a soloution of the towers of hanoi problem by three search ways (BFS-DFS-IDS) so I use "state" class whitch defined by 5 variables as here :
class state {
var $tower1 = array();
var $tower2 = array();
var $tower3 = array();
var $depth;
var $neighbors = array();
and it also has many function one of them is getneighbors() which supposed to fill the array $neighbors with state neighbors and they are from the type "state"
and here is the function :
function getneighbors ()
{
$temp=$this->copy();
$neighbor1= $this->copy();
$neighbor2= $this->copy();
$neighbor3= $this->copy();
$neighbor4= $this->copy();
$neighbor5= $this->copy();
$neighbor6= $this->copy();
if(!Empty($temp->tower1))
{
if(!Empty($neighbor1->tower2))
{
if(end($neighbor1->tower1) < end($neighbor1->tower2))
{
array_unshift($neighbor1->tower2,array_pop($neighbor1->tower1));
array_push($neighbors,$neighbor1);
}}
else
{
array_unshift($neighbor1->tower2, array_pop($neighbor1->tower1));
array_push($neighbors,$neighbor1);
}
if(!Empty($neighbor2->tower3))
{
if(end($neighbor2->tower1) < end($neighbor2->tower3))
{ array_unshift($neighbor2->tower3, array_pop($neighbor2->tower1));
array_push($neighbors,$neighbor2);
}}
else
{
array_unshift($neighbor2->tower3,array_shift($neighbor2->tower1));
array_push($neighbors,$neighbor2);
}
}
if(!Empty($temp->tower2))
{
if(!Empty($neighbor3->tower1))
{
if(end($neighbor3->tower2) < end($neighbor3->tower1))
{ array_unshift($neighbor3->tower1,array_shift($neighbor3->tower2));
array_push($neighbors,$neighbor3);
}
}
else
{
array_unshift($neighbor3->tower1,array_shift($neighbor3->tower2));
array_push($neighbors,$neighbor3);
}
if(!Empty($neighbor4->tower3))
{
if(end($neighbor4->tower2) < end($neighbor4->tower3))
{ array_unshift($neighbor4->tower1,array_shift($neighbor4->tower2));
array_push($neighbors,$neighbor4);
}
}
else{
array_unshift($neighbor4->tower3,array_shift($neighbor4->tower2));
array_push($neighbors,$neighbor4);
}
}
if(!Empty($temp->tower3))
{
if(!Empty($neighbor5->tower1))
{
if(end($neighbor5->tower3) < end($neighbor5->tower1))
{array_unshift($neighbor5->tower1,array_shift($neighbor5->tower3));
array_push($neighbors,$neighbor5);
}
}
else{
array_unshift($neighbor5->tower1,array_shift($neighbor5->tower3));
array_push($neighbors,$neighbor5);}
if(!Empty($neighbor6->tower2))
{
if(end($neighbor6->tower3) < end($neighbor6->tower2))
{ array_unshift($neighbor6->tower2,array_shift($neighbor6->tower3));
array_push($neighbors,$neighbor6);
}}
else{
array_unshift($neighbor6->tower2,array_shift($neighbor6->tower3));
array_push($neighbors,$neighbor6);}
}
return $neighbors;
}
note that toString and equals and copy are defined too
now the problem is that when I call getneighbors() it returns an empty $neighbors array
can you pleas tell me the problem ?
You have a scoping issue. $neighbors is a class variable and not a PHP global. Everywhere you refer to $neighbors change it to $this->neighbors.
Related
I am developing a Register/Login system with validation. Registering system is working well. For example, when I register the same email twice, the following message appears:
Email already registered!
However, when I log-in with the same e-mail and password, an error occurs. The following message appears as a validation error:
Email not registered!
Even if the email is registered in DB.
Code for e-mail validation:
<?php
public function validateEmail($par)
{
if (filter_var($par, FILTER_VALIDATE_EMAIL)) {
return true;
} else {
$this->setErro("Invalid Email!");
return false;
}
}
public function validateIssetEmail($email, $action = null)
{
$b = $this->cadastro->getIssetEmail($email);
if ($action == null) {
if ($b > 0) {
$this->setErro("Email already registered!");
return false;
} else {
return true;
}
} else {
if ($b > 0) {
return true;
} else {
$this->setErro("Email not registered!");
return false;
}
}
}
Code for login controller:
<?php
$validate = new Classes\ClassValidate();
$validate->validateFields($_POST);
$validate->validateEmail($email);
$validate->validateIssetEmail($email,"login");
$validate->validateStrongSenha($senha);
$validate->validateSenha($email,$senha);
var_dump($validate->getErro());
Code for class login:
<?php
namespace Models;
class ClassLogin extends ClassCrud
{
# Returns user data
public function getDataUser($email)
{
$b = $this->selectDB(
"*",
"users",
"where email=?",
array(
$email
)
);
$f = $b->fetch(\PDO::FETCH_ASSOC);
$r = $b->rowCount();
return $arrData = [
"data" => $f,
"rows" => $r
];
}
}
My getIssetEmail method exists on Register code only.
# Check directly at the bank if the email is registered
public function getIssetEmail($email)
{
$b = $this->selectDB(
"*",
"users",
"where email=?",
[
$email
]
);
return $r = $b->rowCount(); // returns the amount of rows in the search
}
And ClassPassword
<?php
namespace Classes;
use Models\ClassLogin;
class ClassPassword
{
private $db;
public function __construct()
{
$this->db = new ClassLogin();
}
# Create password's hash to save in DB
public function passwordHash($senha)
{
return password_hash($senha, PASSWORD_DEFAULT);
}
# Verify if password's hash is correct
public function verifyHash($email, $senha)
{
$hashDb = $this->db->getDataUser($email);
return password_verify($senha, $hashDb["data"]["senha"]);
}
}
This is not an answer but hopefully it will help in debugging.
First, I'm going to change your code. This is 100% a style choice but I personally think it is easier to follow. If you have an if statement that always returns, you don't technically need an else. Once again, this is a style choice and you don't have to follow it.
Second, if you can, try adding logging into your workflow, it will save you so much time debugging. It isn't always an option, especially for legacy code bases, but it is awesome when you can inspect complex code. In this example, I"m just making a couple of helper methods that dump stuff but normally I'd use something like Monolog to write to a stream that I can tail, and I can easily turn it off in production. When logging, sometimes it helps to avoid identical messages so that you can easily find the exact line number you are on, too.
So with those changes, try running this code inside of your class:
private function logMessage($message)
{
echo $message . PHP_EOL;
}
private function logVariable($variable)
{
var_dump($variable);
}
public function validateIssetEmail($email, $action = null)
{
$this->logVariable($email);
$this->logVariable($action);
$b = $this->cadastro->getIssetEmail($email);
$this->logVariable($b);
if ($action === null) {
$this->logMessage('Action was null');
if ($b > 0) {
$this->logMessage('B is greater than zero');
$this->setErro("Email already registered!");
return false;
}
$this->logMessage('B was not greater than zero');
return true;
}
$this->logMessage('Action was not null');
if ($b > 0) {
$this->logMessage('B is greater than zero');
return true;
}
$this->logMessage('B was not greater than zero');
$this->setErro("Email not registered!");
return false;
}
This should log in human-readable form every step. You should be able to walk through this and identify where your bug is. For instance, in the comments above you said that a variable was 0 in a block that was guarded by a check that guarantees that that shouldn't happen.
This is the wrong part i guess you assigned login as action so you can call cadastro class inside of the function
$cadastro = new Cadastro();
$b = $cadastro->getIssetEmail($email);
if ($action == null) {
if ($b > 0) {
$this->setErro("Email already registered!");
return false;
} else {
return true;
}
} else {
if ($b > 0) {
return true;
} else {
$this->setErro("Email not registered!");
return false;
}
}
I am getting null value for function getRecommendation($matrix,$getName), the data obtained are working fine
still learining php
<?php
require('connection.inc.php');
require('recommend.php');
$userID=$_SESSION['USER_ID'];
$reco=mysqli_query($con,"select userrating.*,product.id,product.productName from userrating,product where userrating.userID='$userID' and product.id=userrating.productID");
$matrix=array();
while($rec=mysqli_fetch_array($reco))
{
$users=mysqli_query($con,"select users.name from users where users.id=$rec[userID]");
$username=mysqli_fetch_array($users);
$matrix[$username['name']][$rec['productName']]=$rec['rating'];
$getName= $username['name'];
}
var_dump(getRecommendation($matrix,$getName));
?>
Here is the function code as well, it is for a recommendor system , fur now i jst need this code not to return null value
$value)
{
if(array_key_exists($key,$matrix[$product2]))
{
$similar[$key]=1;
}
}
if($similar==0)
{
return 0;
}
foreach($matrix[$product1] as $key=>$value)
{
if(array_key_exists($key,$matrix[$product2]))
{
$sum=$sum+pow($value - $matrix[$product2][$key],2);
}
}
return 1/(1+sqrt($sum));
}
function getRecommendation($matrix,$prod)
{
foreach($matrix as $otherProduct=>$value)
{
if($otherProduct!=$prod){
$sim=similarityDistance($matrix,$prod,$otherProduct);
var_dump($sim);
}
}
}
?>
You have to actually return something from the function getRecommendation. (That's why you get NULL now. The functions isn't returning anything).
function getRecommendation($matrix,$prod)
{
foreach($matrix as $otherProduct=>$value)
{
if($otherProduct!=$prod){
$sim=similarityDistance($matrix,$prod,$otherProduct);
var_dump($sim);
}
}
//I don't what you want to return. Maybe this, but it has to be something..
return $sim;
}
I'm using custom class to connect to asterisk server via php.
Here it's code:
class Asterisk_ami
{
public $ini = array();
function __construct ()
{
$this->ini["con"] = false;
$this->ini["host"] = "127.0.0.1";
$this->ini["port"] = "****";
$this->ini["lastActionID"] = 0;
$this->ini["lastRead"] = array();
$this->ini["sleep_time"]=1.5;
$this->ini["login"] = "****";
$this->ini["password"] = "****";
}
function __destruct()
{
unset ($this->ini);
}
public function connect()
{
$this->ini["con"] = fsockopen($this->ini["host"], $this->ini["port"],$a,$b,10);
if ($this->ini["con"])
{
stream_set_timeout($this->ini["con"], 0, 400000);
}
}
public function disconnect()
{
if ($this->ini["con"])
{
fclose($this->ini["con"]);
}
}
public function write($a)
{
$this->ini["lastActionID"] = rand (10000000000000000,99999999900000000);
fwrite($this->ini["con"], "ActionID: ".$this->ini["lastActionID"]."\r\n$a\r\n\r\n");
$this->sleepi();
return $this->ini["lastActionID"];
}
public function sleepi ()
{
sleep($this->ini["sleep_time"]);
}
public function read()
{
$mm = array();
$b = array();
$mmmArray=array();
$k = 0;
$s = "";
$this->sleepi();
do
{
$s.= fread($this->ini["con"],1024);
sleep(0.005);
$mmm=socket_get_status($this->ini["con"]);
array_push($mmmArray, $mmm);
} while ($mmm['unread_bytes']);
$mm = explode ("\r\n",$s);
$this->ini["lastRead"] = array();
for ($i=0;$i<count($mm);$i++)
{
if ($mm[$i]=="")
{
$k++;
}
$m = explode(":",$mm[$i]);
if (isset($m[1]))
{
$this->ini["lastRead"][$k][trim($m[0])] = trim($m[1]);
}
}
unset ($b);
unset ($k);
unset ($mm);
unset ($mm);
unset ($mmm);
unset ($i);
unset ($s);
var_dump($mmmArray);
return $this->ini["lastRead"];
//return $s;
}
public function init()
{
return $this->write("Action: Login\r\nUsername: ".$this->ini["login"]."\r\nSecret: ".$this->ini["password"]."\r\n\r\n");
}
}
And here is testAsterisk.php where I try it.
include("./lib/asteriskAmi.php");
$a = new Asterisk_ami();
$a->connect();
if ($a->ini["con"])
{
$a->init();
$a->write("Action: GetConfig\r\nFilename: extensions.conf\r\n");
print_r($a->read());
$a->disconnect();
}
I want to get extension.conf config via ami. The problem is that I don't get full config. 16 last string are alwas missing. However when I check GetConfig via asterisk console it returns full config.
As you can see while cycle is interrupted when unread bytes of socket_get_status are 0, I checked them pushing in array and dumping it, and I can see that unread_bytes are actually 0. I tried changing sleep_time and different timeout parametres, the result was the same.
What else can I check? What can cause this mistake? May be I can use some other func?
Really, only proper solution I've found is to use PAMI, instead of custom class. It's more comfortable for using and anyway it gives me full content of extensions.conf.
there is two ways or more i can make that function
one why is using more returns and return every time i do not need continue with the function and another way is using
more ifs,else ifs, elses,
function getCountOfWhatEverMethodType1
{
$return = false;
// ----
if($user->isLogged)
{
if(getDBOBlaBla->equal(1))
{
$return = 2;
}
else if(getDBOBlaBla->equal(2))
{
$return = 3;
}
else
{
$return = 1;
}
}
// ----
return $return;
}
function getCountOfWhatEverMethodType2
{
if(!$user->isLogged)
{
return false;
}
$return = 1;
// ----
if(getDBOBlaBla->equal(1))
{
$return = 2;
}
else if(getDBOBlaBla->equal(2))
{
$return = 3;
}
// ----
return $return;
}
with one i should use and why?
If you want to return something, usually the better option is to return something when the condition is met.
I would do it this way:
function getCountOfWhatEverMethodType3()
{
if(!$user->isLogged)
{
return false;
}
// ----
if(getDBOBlaBla->equal(1))
{
return 2;
}
if(getDBOBlaBla->equal(2))
{
return 3;
}
return 1;
}
For me this style is better for 2 reasons:
You can remove some if/else statments so you can code faster and there's less code in case you need to modify or analyze that
You don't create temporary variables because you don't need them.
In fact each person has it's own coding preferences in such statements and if all work you can use any of them. But even look at your previous code - you made some mistakes (used null that was unnecessary) and using the above version it would be harder to do such mistake
Someone please explain to me why this doesn't work, and what I am doing wrong. For some reason, when I run the function validateUsername, the $error variable remains completely unchanged, instead of evaluating to true. How is this possible?
Yet, if I remove the code within the function and run it straight without a function call, it works. The example below is so simple it is practically pseudo code, and yet it doesn't work. Is this behavior unique to PHP? I don't want to run into this again in some other language.
<?php
$username = 'danielcarvalho';
$error = false;
function validateUsername()
{
if (strlen($username) > 10)
{
$error = true;
}
}
validateUsername();
if ($error == false)
{
echo 'Success.';
}
else
{
echo 'Failure.';
}
?>
This isn't working because $username isn't available within the scope of your validateUsername function. (Neither is the $error variable.) See the variable scope section of the PHP manual for more information.
You could fix this by adding global $username, $error; within your function, although this isn't a particularly elegant approach, as global variables are shunned for reasons too detailed to go into here. As such, it would be better to accept $username as an argument to your function as follows:
<?php
function validateUsername($username) {
if (strlen($username) > 10) {
return false;
}
return true;
}
if (validateUsername('danielcarvalho')) {
echo 'Success.';
}
else {
echo 'Failure.';
}
?>
$error has local scope in function validateUsername. To access global variables, use global keyword.
Read about scopes here. Change your function to:
function validateUsername($username)
{
global $error;
if (strlen($username) > 10)
{
$error = true;
}
}
validateUsername($username);
Better implementation using function parameter:
function validateUsername($username, &$error)
{
if (strlen($username) > 10)
{
$error = true;
}
}
validateUsername($username, $error);
Another implementation:
function validateUsername($username)
{
if (strlen($username) > 10)
{
return true;
}
return false;
}
$error = validateUsername($username);