recursive function in php class - php

I want to create a function in class, to create username, function will check if username exist then it will increment username like username_1. and check if this username exist or not if it exist again increment it to username_2 till new username created. I have created this function but it return me nothing.Please help me what is wrong in my code.
class a{
function check_username($username){
if($usernameexist){
return true;
}
else
{
return false;
}
}
function create_username($username) {
$__name = __FUNCTION__;
if ($this->check_username($username)) {
$n++;
$username = $username . "_" . $n;
//return $__name($username); this return fatal error.
return call_user_func('create_username', $username);
} else {
return $username;
}
}
}

No need to use recursion for this, a simple while(){} loop will do:
Plain-Jane Interator method
// your original function
function create_username($username){
// check if the username (as-is) already exists
if ($this->check_username($username)){
// use $n to keep a counter
$n = 1;
// while {username}_{n} exists, keep incrementing the counter
while ($this->check_username($username.'_'.$n)){
$n++;
/* If you don't want this to check to infinity, uncomment
* the below portion. the 100 is an arbitrary number, but use
* whatever you want as a limitation (could even make it a
* parameter in the method). Also, returning FALSE allows you to
* gracefully catch when max attempts are reached.
*
* e.g.
* if (($new_user = $obj->create_username('BradChristie')) !== FALSE){
* // user was successfully created within the max allowed attempts
* }
*/
//if ($n > 100) return FALSE
}
// return the result
return $username.'_'.$n;
}
// username was fine, return it back
return $username;
}
Recursive method
// recursive username check
public function create_username($username, $n = 0)
{
/* Same as above function, this is a check to prevent counting
* to infinity. uncomment to apply it
*/
//if ($n > 100) return FALSE;
// establish the username we're testing. if $n is 0,
// it's the original call to the function (don't add _0)
// if it's >0, it's part of the search so include it
$_username = $username . ($n > 0 ? '_'.$n : '');
// check if the username exists.
if ($this->check_username($_username))
{
// it exists, so make a call to this same function passing
// the original username and the value of n + 1 (move to next
// possibility)
return $this->create_username($username, $n+1);
}
// the name, as-is, was fine. return it
return $_username;
}
Example

Your code is wrong in several ways and, as pointed out elsewhere, your desired function is better written iteratively.
Some of the problems with your code are as follows:
You are doing your recursive check when check_username has succeeded. So, if you fail to find the original $username you are never modifying it, so never checking the modified value.
You are modifying the name passed to create_username by appending _n (for appropriate n). Since you are passing a modified name in your recursive call you will actually end up with multiple _n parts on the name.
Since you are not limiting your recursive calls, even if this was written correctly, you would eventually get nested too deep.

There is no need for recursivity in this case... A simple loop would do just perfectly:
function create_username($username) {
$original_username = $username;
$i=1;
while(! $this->check_username($username) ) {
$username = $original_username . '_' .$i++;
}
return $username;
}

Related

Function and if else in PHP

i dont understand how the if statement works and the function is called, why i am getting "He has more strength", i know because the strength is greater, but what i am getting there, is it a boolean? can i dump it, it shows me NULL if i put this inside the if statement
edit:i have added the return.
<?php
class Ship
{
public $name;
public $strength = 0;
public function doesGivenShipHaveMoreStrength($givenShip)
{
return $givenShip->strength > $this->strength;
}
}
$myShip = new Ship();
$myShip->name = 'TIE Fighter';
$myShip->strength = 150;
$otherShip = new Ship();
$otherShip->name = 'Imperial Shuttle';
$otherShip->strength = 50;
if ($myShip->doesGivenShipHaveMoreStrength($otherShip)) {
echo $otherShip->name.' He has more strength';
} else {
echo $myShip->name.' She has more strength';
}
?>
If statements evaluates whatever inside it's braces () . if true or 1 the block or statement will be executed. your function returned a value , and that returned value is later evaluated by the if statement. these are examples that might help you understand how if statements work. the same goes with almost every other programming language.
//example 1
if(true){
// will be executed
}else{
// will not executed
}
//example 2
if(false){
// will not executed
}else{
// will be executed
}
//example 3
if( 2 > 1){
// will be executed
}else{
// will not executed
}
//example 4
if(1){
// will be executed
}else{
// will not executed
}
//example 5
if(0){
// will not executed
}else{
// will be executed
}
//example 5
if(myFunction()){
// will be executed
}else{
// will not executed
}
function myFunction()
{
return true;
}
Your class is not written properly, it should be :
class Ship
{
public $name;
public $strength = 0;
public function doesGivenShipHaveMoreStrength($givenShip)
{
return ($givenShip->strength > $this->strength);
}
}
Then it will work as expected :) In your version, the function does return nothing, as a result when you use it, it evaluates to NULL, which is equivalent to false, and your test block fails !
I would add one more point to the recently answers.
You must add return.
Even you add the return, you shall hit your block containing "He has more strength".
Reason: you are comparing with this->strength which is 0 and your both objects have strength set to 150 & 50 accordingly. It's going to be always true.
I would suggest to compare object level values if you are really want to achieve the same functionality.
Revised Answer: You may need to adjust/fix your condition.
as per your code snippet at here
Your value of given ship shall be printed as 50 and current object value is 150 . your function is checking if 50 > 150? answer would be false and you shall hit your else.
Hope this helps

Calling an associative array that's in a class

Pretty sure there's a simple solution to this that I'm not seeing, but currently trying to create a simple system that checks the user's username and password input before allowing them to proceed. If the checks don't hold up, an error message is displayed indicating what was wrong with their input. I'm attempting this through an associative array like so:
public function check() {
if (strlen($this->_username) < $this->_minimumChars) {
$this->_error['idlength'] = "Username needs to be longer than $this->_minimumChars characters";
}
if (!preg_match('/^[a-zA-Z0-9]+$/', $this->_username)) {
$this->_error['idformat'] = "Username can only contain letters and numbers";
}
if (strlen($this->_password) < $this->_minimumChars) {
$this->_error['pwdlength'] = "Password must be longer than $this->_minimumChars characters";
}
if (empty($this->_error)) {
return $this->_result = true;
} }
I have initiated the $_error variable as protected $_error = array();
And I'm trying to call the method
public function getError() {
return $this->_error; }
By using $errors = $checker->getError(); where $checker is an instance of the class.
However, when I try using the $errors array it seems there's nothing initiated. I've tried troubleshooting it through using empty($errors['idlength']) in a conditional statement and it seems there's no elements inside the array.
Can anyone tell me where I'm going wrong?

Conditional return in a PHP function

I have a return statement in my function:
function fun($result)
{
$counter = 0;
while($row=mysql_fetch_array($result))
{
/*if($counter==2)
{
return $name;
}*/
$user=$row['message'];
$sql2="select username from members where id='$user'";
$result2=mysql_query($sql2);
$row2=mysql_fetch_array($result2);
$name .= $row2['username']." and ";
$counter++;
if($counter==2)
{
return $name;
}
}
}
The return block (commented) doesn't work which immediately terminates the execution of the function irrespective of the condition. But the return block if placed in position as shown in the code just works fine. Why?
I want to return only 2 rows. It seems that it should work whether it is placed before or after,because it depends on the value of the counter. Check the condition before adding new row to $name variable.First row will be added to $name and $counter is incremented,then check the condition and so on.What is wrong?
Function doesn't return anything when there are less than 3 rows even if you want to return when you reach 2, you need 3 rows minimal.
The function checks $counter in the loop after you handled your 2nd row.
So there need to be at least 3 rows for the function to return the $ name. This is weird because you want it to return then there are 2 names found.
The function doesn't necessarily terminates, but simply doesn't return anything.
Your function may never reach the return statement. You have to check for both conditions to be false and then return $name if they are. A for loop should do what you need.
function fun($result)
{
for($cnt=0; ($row=mysql_fetch_array($result)) AND $cnt<2; $cnt++)
{
$name .= 'Your Data';
}
return $name;
}

Code doesn't make sense -- two conditionals within PHP try

I have inherited an application that is not doing what it's supposed to do. I have isolated the problem to the database not being properly attached. The programmer wrote this function that seemingly is suppose to evaluate whether the database is attached, calling the "attachPaymentDatabase()" function to attach it if it's not.
function attachPaymentDatabaseIfNotDoneAlready()
{
global $db;
global $hasPaymentDatabaseAttached;
// Determine if we have attached the payment tables, and if not, add them.
$hasPaymentDatabaseAttached = false;
try {
// this new way should work the best-- looking for PAY.
$alldb = queryall($db, "PRAGMA database_list;");
for ($i = 0; $i < count($alldb); $i++)
{
$alldb[$i] = array_change_key_case($alldb[$i], CASE_LOWER);
if (strtolower($alldb[$i]['name']) == 'pay')
{
debugEmail("condition 1 worked.");
$hasPaymentDatabaseAttached = true;
break;
}
}
// if its name changed this will also work
if (!$hasPaymentDatabaseAttached)
{
$r = #$db->querySingle("SELECT * FROM PAY_PARAMETER;");
$hasPaymentDatabaseAttached = true;
debugEmail("condition 2 worked.");
}
}
catch(Exception $e)
{
}
if (!$hasPaymentDatabaseAttached)
{
debugEmail("nothing worked.");
attachPaymentDatabase();
}
}
I have written a debugEmail() function that emails me a defined message with a timestamp as used above. When executing the code from the application, I can see that "condition 2 worked." is being called one second before "nothing worked.".
I don't understand how this can be. If debugEmail("condition 2 worked."); is executing, then so should too $hasPaymentDatabaseAttached = true; in which case this should not execute:
if (!$hasPaymentDatabaseAttached)
{
debugEmail("nothing worked.");
attachPaymentDatabase();
}
But it clearly is.
What is going on here?!?!?!?
No it shouldn't, because $hasPaymentDatabaseAttached is set to true in the first condition. In still nonsense at all, but it works as described.

Do in_array have a like function?

I have an array of people that is registered as online in a html file. I am using this so that each can have an image assigned to them. But when checking to see if using name is already in use the in_array function return false and allow the script to continue.
$user = "< img src='default.jpg' />John";
$explode = array("<img src='tress.jpg' />John");
if(in_array($user, $explode))
{
//show login script if user exists
}
else
{
//continue to script
}
Now the reason this is not working is because the john in the array is not identical to the john in $user. Is there anyway of checking that the name exists in the array? When responding please explain.
Instead of asking, "How do I solve this problem?", you need to start with, "Why am I having this problem?"
$user = "< img src='default.jpg' />John";
Is < img src='default.jpg' />John a user name? Why are you using it as one? I'm guessing there's some clever thought behind this like "Well, I always display a user's image with their name, so I'll just make the image part of their name. This is going to cause far more problems than it solves. This comes back to a big concept in computer science called separation of concerns. An image is not logically a part of a user name, so don't store it as one. If you always display them together, you can use functions to display a user's information in a standard way without making the image part of the user name.
So first off, remove the image from the name. There are several ways to store this separately.
I would suggest using a class:
class User {
public $name;
public $imageSource;
// The following functions are optional, but show how a class
// can be useful.
/**
* Create a user with the given name and URL to their image
*/
function __construct($name, $imageSource) {
$this->name = $name;
$this->imageSource = $imageSource;
}
/**
* Gets the HTML to display a user's image
*/
function image() {
return "<img src='". $this->imageSource ."' />";
}
/**
* Gets HTML to display to identify a user (including image)
*/
function display() {
return $this->image() . $this->name;
}
}
$user = new User("john", "default.jpg");
// or without the constructor defined
//$user = new User();
//$user->name = "john";
//$user->imageSource = "default.jpg";
echo $user->display();
You can use an "array" if you want to be a little lazier, but I don't recommend it in the general case, since you lose the cool features of classes (like those functions):
$user = array(
name => "john",
image => "<img src='default.jpg' />";
);
echo $user["image"] . $user["name"];
In your database (if you're using one), make them separate columns and then use one of the above data structures.
Now that you have this, it's easy to see if a user name is in a given list using a foreach loop:
function userNameInList($user, $users) {
for($users as $current) {
if($user->name == $current) {
return true;
}
}
return false;
}
$newUser = new User("John", "john.jpg");
$currentUsers = array("John", "Mary", "Bob");
if(userNameInList($newUser, $currentUsers) {
echo "Sorry, user name " . $newUser->name . " is already in use!";
}
If you're new to PHP, the normal for loop may be easier to understand:
function userNameInList($user, $users) {
for($i = 0; $i < count($users); ++i) {
$current = $users[$i];
if($user->name == $current) {
return true;
}
}
return false;
}
Let me know if any of this doesn't run, I don't write PHP very often anymore..

Categories