I have a few variables namely $tv, $car, $refrigerator, $laptop and $desktop which take values 0/1 to indicate presence or absence YES/NO.
Is there an easy way to convert these from 1/0 to YES/NO?
Something which makes the below easier
<?php
$tv = 1;
$car = 0;
$refrigerator = 1;
$laptop = 1;
$desktop = 0;
if($tv == 1)
$tv = "YES";
else
$tv = "NO";
print($tv);
if($car == 1)
$car = "YES";
else
$car= "NO";
print($car);
//Repeat so on for refrigerator, laptop , desktop
?>
You can write a function so you don't repeat your code over and over.
function yesNo(&$value){
$value = $value == true ? 'Yes' : 'No';
}
yesNo($car);
yesNo($tv);
For learning propose it seems a little to complicated to me to use a function with references. So I decided to write this little example as near as possible on the given code and without references, but return values and without typecasts.
1 and 0 are integers and not boolean variables. So we will use === comparison operator to avoid type juggling:
<?php
/**
* Convert number to 1 to'YES' or everything else to 'NO'.
* #param $n the number to convert.
* #return string YES|NO
*/
function numberToString($n)
{
return $n === 1 ? 'YES' : 'NO';
}
$tv = 1;
$car = 0;
$refrigerator = 1;
$laptop = 1;
$desktop = 0;
// Call numberToString function for $tv and print return value
print(numberToString($tv));
// Call numberToString function for $car and print return value
print(numberToString($car));
// Call numberToString function for $refrigerator and print return value
print(numberToString($refrigerator));
// Call numberToString function for $laptop and print return value
print(numberToString($laptop));
// Call numberToString function for $desktop and print return value
print(numberToString($desktop));
?>
And if you feel lucky you can also use array with foreach:
<?php
/**
* Convert number to 1 to'YES' or everything else to 'NO'.
* #param $n the number to convert.
* #return string YES|NO
*/
function numberToString($n)
{
return $n === 1 ? 'YES' : 'NO';
}
// For php >= 5.4 you can also use the new array syntax:
// $devices = [
// 'tv' => 1,
// 'car' => 0,
// 'refrigerator' => 1,
// 'laptop' => 1,
// 'desktop' => 0,
// ];
$devices = array(
'tv' => 1,
'car' => 0,
'refrigerator' => 1,
'laptop' => 1,
'desktop' => 0,
);
foreach ($devices as $device) {
// Call numberToString function for $tv and print return value
print(numberToString($device));
}
?>
Happy coding.
skroczek's method worked for me in an array, but I had to update to the following for it to work:
function numberToString($n)
{
return $n == 1 ? 'YES' : 'NO';
}
for those who see this post recently
filter_var function does this with ease
var_dump(filter_var('oops', FILTER_VALIDATE_BOOLEAN)); // bool(false)
var_dump(filter_var('no', FILTER_VALIDATE_BOOLEAN)); // bool(false)
var_dump(filter_var('yes', FILTER_VALIDATE_BOOLEAN)); // bool(true)
var_dump(filter_var('1', FILTER_VALIDATE_BOOLEAN)); //bool(true)
var_dump(filter_var('0', FILTER_VALIDATE_BOOLEAN)); //bool(false)
var_dump(filter_var('2', FILTER_VALIDATE_BOOLEAN)); //bool(false)
Related
I created a small function that helps me build an array (i use it to populate a select2 element). It works great but it doesn't accept 0 as the starting number.
Although it is not really crucial i would really want to understand why this happens and how to fix it.
Here is the function:
function create_numstring_array($startNum, $endNum, $jumps, $sideString = NULL) {
if($startNum && $endNum) {
$data = array();
$counter = intval($startNum);
while($endNum > $counter ) {
$data["$counter"] = $counter.' '.$sideString;
$counter = $counter + $jumps;
// echo $counter."<br />";
}
return $data;
}
}
/* DOESNT WORK
echo '<pre>Code:'."<br />";
print_r(create_numstring_array(0, 9, 0.5, ''));
echo '</pre>'."<br />";
*/
/* WORKS! */
echo '<pre>Code:'."<br />";
print_r(create_numstring_array(1, 9, 0.5, ''));
echo '</pre>'."<br />";
I guess it gets stuck in this part
while($endNum > $counter) {
Since $counter = 0 but how can i overcome this?
Because (bool)0 == False. So, your code fails, because you are testing $startNum and it is treated as boolean false.
Change it to something more reasonable, for example: if (is_int($startNum) ... or functions like that (is_numeric could be candidate)
function create_numstring_array($startNum, $endNum, $jumps, $sideString = NULL){
#check for valid input
#(can be float or integer so lets end always greater than start)
if($startNum>$endNum || !is_numeric($jumps)) {
return null;
}
#create the range
$keys = range($startNum, $endNum, $jumps);
#create values with or without sideString
$values = ($sideString)
? array_map(function($a) use ($sideString){ return $a.' '.$sideString;},$keys)
: $keys;
#return the new array
return array_combine($keys,$values);
}
echo '<pre>Code:'."<br />";
print_r(create_numstring_array(0, 9, 0.5, ''));
echo '</pre>'."<br />";
Why your version is not working, is explained in the comments, so here a working version, that check for valid input and valid jumbs. (Works with float and integer). Remove/Skipp last and first entry is they are not needed.
i have this inside a php function:
$result = new stdClass();
$result->domainname = $domainName;
$result->element = $element;
$result->availability = $availability;
return ($result);
so its returning all of the values in the $result variable
when i do a print_r on the function, the results display like this:
stdClass Object
(
[domainname] => domain.com
[element] =>
[availability] => false
)
i am calling the function with this code:
$domain = domainNameCheck($_GET["domain"].'.'.$_GET["tld"]);
so i tried to get the returned by doing $domain->availability but its not returning the value, example:
if($domain->availability) {
echo 'yes';
} else {
echo 'no';
}
am i trying to get the data the incorrect way?
UPDATE
the full function is:
if(!function_exists("domainNameCheck")) {
function domainNameCheck($domainName, $element) {
$result = '';
$client = new IcukApiClient();
$client->username = "username";
$client->key = "pass";
$client->encryption = "SHA-512";
$req = new IcukApiRequest();
$req->url = "/domain/availability/" . $domainName;
$req->method = "GET";
$res = $client->send($req);
$availability = 'unknown';
if ($res->success) {
$obj = json_decode($res->response);
$availability =($obj->available) ? 'true' : 'false';
}
else {
$availability = 'unknown';
}
$result = new stdClass();
$result->domainname = $domainName;
$result->element = $element;
$result->availability = $availability;
return ($result);
}
}
Your main problem seems to be that you are calling a function with 2 parameters but passing only one parameter
function domainNameCheck($domainName, $element) {}
// called like this (one parameter)
$domain = domainNameCheck($_GET["domain"].'.'.$_GET["tld"]);
This should be generating a compile error!
Also here
if ($res->success) {
$obj = json_decode($res->response);
// check what $obj->available is set to
// it may also be a string and not a boolean
print_r($obj);
$availability =($obj->available) ? 'true' : 'false';
}
else {
$availability = 'unknown';
}
Please note that there are two error/warning messages PHP is giving:
E_WARNING : type 2 -- Missing argument 2 for domainNameCheck()
E_NOTICE : type 8 -- Undefined variable: element
You should fix those errors, and make sure you are informed of errors during development.
Secondly, you have defined your availability as a string by assigning "false", "true", or "unknown". So when you do this:
if($domain->availability) {
... that will be true for all three values, because strings are true for PHP when converted to boolean (except when empty). To illustrate, this will echo "hello":
if ("false") echo "hello";
So you need to change your test like this:
if($domain->availability === "true") {
Or, If you want to define $domain->availability as a true boolean, then you need to alter the assignments in your function, like this:
....
$availability = $obj->available; // assuming that is a boolean!
}
else {
$availability = null; // unknown
}
... and then you can do what you had:
if($domain->availability) {
Likely because $domain->availability is boolean
To output you can first check whether its true or false and output accordingly
here's a simple example:
if ($domain->availability){
echo 'Available';
}
else {
echo 'Not Available';
}
I have a series of object keys:
$this->rules->days->mon = isset($this->recurring_event_data['post_ar'][$this->rules->type]['mon']) ? true : false;
$this->rules->days->tue = isset($this->recurring_event_data['post_ar'][$this->rules->type]['tue']) ? true : false;
$this->rules->days->wed = isset($this->recurring_event_data['post_ar'][$this->rules->type]['wed']) ? true : false;
$this->rules->days->thu = isset($this->recurring_event_data['post_ar'][$this->rules->type]['thu']) ? true : false;
$this->rules->days->fri = isset($this->recurring_event_data['post_ar'][$this->rules->type]['fri']) ? true : false;
$this->rules->days->sat = isset($this->recurring_event_data['post_ar'][$this->rules->type]['sat']) ? true : false;
$this->rules->days->sun = isset($this->recurring_event_data['post_ar'][$this->rules->type]['sun']) ? true : false;
I have this function:
function calc_next_weekly_interval($ii,$i)
{
global $array;
// we will roll through this->rules->mon,tue,wed,thu,fri,sat,sun. If its true, return the new iii value, if not keep looping through the array until we hit true again.
$cur_day = strtolower(date('D',$ii));
$found_today = false;
// our initial start date
$iii = $ii;
foreach($this->rules->days as $day => $value)
{
if($found_today == true && $value = true)
{
return $iii
}
// need to find the current day first!
if($day == $cur_day)
{
$found_today = true;
}
$iii + SECS_PER_DAY;
}
}
all good. Note I am trying to find the next true day from the current day. Issue is when I do a search using a Sunday as the initial cur_day, obviously the foreach loop will stop before it finds a true match. How can I continuously loop through an array (Or object keys)? Should I put the loop in a new function and keep calling it with a new start date? I don't want to add extra array keys->values as it will affect things later, I have thought about adding to the initial array only in this function (example here, the array is coded for reference, but in my class - it is of course obj keys->values
If you want to loop continually you can use
$infinate = new InfiniteIterator(new ArrayIterator($array));
foreach ( $infinate as $value ) {
// Do your thing
// Remember to break
}
How about
foreach($this->rules->days as $day => $value)
{
if($day == $cur_day)
{
$set = true;
}
$iii + SECS_PER_DAY;
if($found_today == true && $value = true)
{
return $iii
}
// need to find the current day first!
}
I have a form that contains a number of textboxes i.e. Volome, Gain, Treble, Middle and Bass. Only whole numbers can be entered, which is validated with javascript and the Maxlength is set to, so no problem there. But how do I make sure that only numbers between 0 and 65535 are entered.
<?php
$name = $_POST['ampMod'];
$volume = 'Volume = '. $_POST['volume'];
$gain = 'Gain = '. $_POST['gain'];
$treble = 'Treble = '. $_POST['treble'];
$middle = 'Middle = '. $_POST['middle'];
$bass = 'Bass = '. $_POST['bass'];
if($volume != null && $gain != null && $treble != null && $middle != null && $bass != null)
{
echo "<h3> $name </h3>";
echo "<table><tr>";
echo "<td>$volume</td>";
echo "<td>$gain</td>";
echo "<td>$treble</td>";
echo "<td>$middle</td>";
echo "<td>$bass</td>";
}
else
{echo ("Please try again. Values must be between 0-65535. 0=Off 65535=Full On 10<br>Click here to try again!");}
?>
It is important to mention that your $volume, $gain, $treble, $middle and $bass will never actually be null as you have assigned a string to them in addition to the $_POST value. In addition you should always check if the $_POST values exist before trying to use them (or you will get an undefined notice message).
Here is an example for a PHP version based on the code you had (untested, but should work fine).
<?php
function isValidRange( $value, $low = 0, $high = 65535) {
// validate / cast value as int (add additional validation here
$value = (int)$value;
if ( $value > $high || $value < $low ) {
// return null (not a valid value)
return null;
}
// otherwise the value is valid so return it
return $value;
}
// make sure the $name var is safe to use
$name = ( isset($_POST['ampMod']) ) ? htmlentities($_POST['ampMod'],ENT_QUOTES,'UTF-8') : null;
$volume = ( isset($_POST['volume']) ) ? isValidRange($_POST['volume']) : null;
$gain = ( isset($_POST['gain']) ) ? isValidRange($_POST['gain']) : null;
$treble = ( isset($_POST['treble']) ) ? isValidRange($_POST['treble']) : null;
$middle = ( isset($_POST['middle']) ) ? isValidRange($_POST['middle']) : null;
$bass = ( isset($_POST['bass']) ) ? isValidRange($_POST['bass']) : null;
if( isset($volume) && isset($gain) && isset($treble) && isset($middle) && isset($bass) )
{
echo "<h3> $name </h3>";
echo "<table><tr>";
echo "<td>Volume = $volume</td>";
echo "<td>Gain = $gain</td>";
echo "<td>Treble = $treble</td>";
echo "<td>Middle = $middle</td>";
echo "<td>Bass = $bass</td>";
echo "</tr></table>";
} else {
echo ("Please try again. Values must be between 0-65535. 0=Off 65535=Full On 10<br>Click here to try again!");}
?>
Lastly I would not recommend just relying on JavaScript to actually check if your values are safe to use (i.e. echo them out), but using js as a pre-warning to users and then properly validating with PHP is the best way to go.
Just do something like this? Don't know why you would want to go between 0 and 65535. I doubt you want them to go that high. If you do just change 10 to 65535
if($value > 10 || $value < 0)
{
echo "Value cant be higher then 10 or lower then 0";
}
This makes sure the value is between 10 and 0
In situations like this, I often prefer to silently clean the form input. You've got client-side validation in place already. If the value is higher than allowed, just set the value to the maximum allowed instead of showing an error message.
// Clean the posted data and prevent notices if not set
$volume = (isset($_POST['volume'])) ? (int) $_POST['volume'] : 0;
// Make sure the value is within a certain range
$min = 0;
$max = 10;
$volume = min($max, max($min, $volume));
You can make use of the filter extension (bundled by default since 5.2):
$FILTER_VALIDATE_KNOB = array(
'filter' => FILTER_VALIDATE_INT,
'options' => array(
'min_range' => 0,
'max_range' => 65535,
)
);
$res = filter_input_array(INPUT_POST, array(
'ampMod' => $FILTER_VALIDATE_KNOB,
'volume' => $FILTER_VALIDATE_KNOB,
'gain' => $FILTER_VALIDATE_KNOB,
'treble' => $FILTER_VALIDATE_KNOB,
'middle' => $FILTER_VALIDATE_KNOB,
'bass' => $FILTER_VALIDATE_KNOB,
));
if (is_null($res) || in_array(null, $res, true)) {
// some or all fields are missing
// - missing fields have null value
} elseif (in_array(false, $res, true)) {
// some or all fields have a wrong value
// - wrong values have false value
}
I would do it with javascript. That way, you wouldn't have to submit the form and if the user types a higher number the alert (or something nicer) is shown:
In the input field, just call the javascript function:
<input id="thefirstnumbervalue" type="text" onchange="checknumber('thefirstnumbervalue')" />
<input id="thesecondnumbervalue" type="text" onchange="checknumber('thesecondnumbervalue')" />
In the function:
function checknumber(theid){
var mynumbervalue = document.getElementById(theid).value;
if (mynumbervalue > 65535){
document.getElementById(theid).value = "65535";
alert("Please try again. Values must be between 0-65535. ...");
}
if(mynumbervalue < 0){
document.getElementById(theid).value = "0";
alert("Please try again. Values must be between 0-65535 ...");
}
}
This is a simple approach in raw javascript. If you use ajax and jquery the result could be easier and nicer. This is complementary to the php solution, as you should also check the data before inserting in your database.
I'm trying to loop through a set of records, all of which have a "number" property. I am trying to check if there are 3 consecutive records, e.g 6, 7 and 8.
I think i'm almost there with the code below, have hit the wall though at the last stage - any help would be great!
$nums = array();
while (count($nums <= 3))
{
//run through entries (already in descending order by 'number'
foreach ($entries as $e)
{
//ignore if the number is already in the array, as duplicate numbers may exist
if (in_array($e->number, $num))
continue;
else
{
//store this number in the array
$num[] = $e->number;
}
//here i need to somehow check that the numbers stored are consecutive
}
}
function isConsecutive($array) {
return ((int)max($array)-(int)min($array) == (count($array)-1));
}
You can achieve the same result without looping, too.
If they just have to be consecutive, store a $last, and check to make sure $current == $last + 1.
If you're looking for n numbers that are consecutive, use the same, except also keep a counter of how many ones fulfilled that requirement.
$arr = Array(1,2,3,4,5,6,7,343,6543,234,23432,100,101,102,103,200,201,202,203,204);
for($i=0;$i<sizeof($arr);$i++)
{
if(isset($arr[$i+1]))
if($arr[$i]+1==$arr[$i+1])
{
if(isset($arr[$i+2]))
if($arr[$i]+2==$arr[$i+2])
{
if(isset($arr[$i+3]))
if($arr[$i]+3==$arr[$i+3])
{
echo 'I found it:',$arr[$i],'|',$arr[$i+1],'|',$arr[$i+2],'|',$arr[$i+3],'<br>';
}//if3
}//if 2
}//if 1
}
I haven't investigated it thoroughly, maybe can be improved to work faster!
This will confirm if all items of an array are consecutive either up or down.
You could update to return an array of [$up, $down] or another value instead if you need direction.
function areAllConsecutive($sequence)
{
$up = true;
$down = true;
foreach($sequence as $key => $item)
{
if($key > 0){
if(($item-1) != $prev) $up = false;
if(($item+1) != $prev) $down = false;
}
$prev = $item;
}
return $up || $down;
}
// areAllConsecutive([3,4,5,6]); // true
// areAllConsecutive([3,5,6,7]); // false
// areAllConsecutive([12,11,10,9]); // true
Here's an example that can check this requirement for a list of any size:
class MockNumber
{
public $number;
public function __construct($number)
{
$this->number = $number;
}
static public function IsListConsecutive(array $list)
{
$result = true;
foreach($list as $n)
{
if (isset($n_minus_one) && $n->number !== $n_minus_one->number + 1)
{
$result = false;
break;
}
$n_minus_one = $n;
}
return $result;
}
}
$list_consecutive = array(
new MockNumber(0)
,new MockNumber(1)
,new MockNumber(2)
,new MockNumber(3)
);
$list_not_consecutive = array(
new MockNumber(5)
,new MockNumber(1)
,new MockNumber(3)
,new MockNumber(2)
);
printf("list_consecutive %s consecutive\n", MockNumber::IsListConsecutive($list_consecutive) ? 'is' : 'is not');
// output: list_consecutive is consecutive
printf("list_not_consecutive %s consecutive\n", MockNumber::IsListConsecutive($list_not_consecutive) ? 'is' : 'is not');
// output: list_not_consecutive is not consecutive
If u don't wanna mess with any sorting, picking any of three numbers that are consecutive should give you:
- it either is adjacent to both the other numbers (diff1 = 1, diff2 = -1)
- the only number that is adjacent (diff = +-1) should comply the previous statement.
Test for the first condition. If it fails, test for the second one and under success, you've got your secuence; else the set doesn't comply.
Seems right to me. Hope it helps.
I think you need something like the following function (no need of arrays to store data)
<?php
function seqOfthree($entries) {
// entries has to be sorted descending on $e->number
$sequence = 0;
$lastNumber = 0;
foreach($entries as $e) {
if ($sequence==0 or ($e->number==$lastNumber-1)) {
$sequence--;
} else {
$sequence=1;
}
$lastNumber = $e->number;
if ($sequence ==3) {
// if you need the array of sequence you can obtain it easy
// return $records = range($lastNumber,$lastNumber+2);
return true;
}
}
// there isn't a sequence
return false;
}
function isConsecutive($array, $total_consecutive = 3, $consecutive_count = 1, $offset = 0) {
// if you run out of space, e.g. not enough array values left to full fill the required # of consecutive count
if ( $offset + ($total_consecutive - $consecutive_count ) > count($array) ) {
return false;
}
if ( $array[$offset] + 1 == $array[$offset + 1]) {
$consecutive_count+=1;
if ( $consecutive_count == $total_consecutive ) {
return true;
}
return isConsecutive($array, $total_consecutive, $consecutive_count, $offset+=1 );
} else {
return isConsecutive($array, $total_consecutive, 1, $offset+=1 );
}
}
The following function will return the index of the first of the consecutive elements, and false if none exist:
function findConsecutive(array $numbers)
{
for ($i = 0, $max = count($numbers) - 2; $i < $max; ++$i)
if ($numbers[$i] == $numbers[$i + 1] - 1 && $numbers[$i] == $numbers[$i + 2] - 2)
return $i;
return false;
}
Edit: This seemed to cause some confusion. Like strpos(), this function returns the position of the elements if any such exists. The position may be 0, which can evaluate to false. If you just need to see if they exist, then you can replace return $i; with return true;. You can also easily make it return the actual elements if you need to.
Edit 2: Fixed to actually find consecutive numbers.