How to set this cases depends on if rule - php

if i've the following
$x = "go";
$y = "went";
$z "gone";
and i need to set title where title will be
$title = $x; //only if "y" empty no care about "z" if empty or not
$title = $x . " - " . $y; // if "y" not empty and "z" is empty
$title = $y . " - " . $z; // if "z" not empty and "y" not empty
this is my try but field and/or looks so permeative (i'm noob)
$empty = ""; // i've creaty empty example
$x = "go";
$y = "went";
$z "gone";
if ($y==$empty) {
$title = $x; // output should be go
} else if($y!=$empty && $z==$empty) {
$title = $x . " - " . $y; // output should be go - went
} else if($y!=$empty && $z!=$empty) {
$title = $y . " - " . $z; // output should be went - gone
} else {
$title = $x; // output should be go
}
do anyone have better suggestion ! thanks a lot

$title = empty($y) ? $x : (empty($z) ? $x."-".$y : $y."-".$z);

Related

Combining array elements with " mark at both ends

I need to combine two or more array elements enclosed inside a double quotation mark...
Example:
- Before -
[
"Foo1",
"\"Foo2",
"Foo3",
"Foo4\"",
"Foo5"
]
-After -
[
"Foo1",
"\"Foo2 Foo3 Foo4\"",
"Foo5"
]
Below, $source and $result are the source and result respectively. I would use array_reduce()
$result = array_reduce($source, function($acc,$i) {
static $append = false; // static so value is remembered between iterations
if($append) $acc[count($acc)-1] .= " $i"; // Append to the last element
else $acc[] = $i; // Add a new element
// Set $append=true if item starts with ", $append=false if item ends with "
if(strpos($i,'"') === 0) $append = true;
elseif (strpos($i,'"') === strlen($i)-1) $append = false;
return $acc; // Value to be inserted as the $acc param in next iteration
}, []);
Live demo
function combine_inside_quotation($array)
{
if(!is_array($array) || 0 === ($array_lenght = count($array))) {
return [];
}
$i = 0;
$j = 0;
$output = [];
$inside_quote = false;
while($i < $array_lenght) {
if (false === $inside_quote && '"' === $array[$i][0]) {
$inside_quote = true;
$output[$j] = $array[$i];
}else if (true === $inside_quote && '"' === $array[$i][strlen($array[$i]) - 1]) {
$inside_quote = false;
$output[$j] .= ' ' . $array[$i];
$j++;
}else if (true === $inside_quote && '"' !== $array[$i][0] && '"' !== $array[$i][strlen($array[$i]) - 1]) {
$output[$j] .= ' ' . $array[$i];
} else {
$inside_quote = false;
$output[$j] = $array[$i];
$j++;
}
$i++;
}
return $output;
}
Try this function it gives the output you mentioned.
Live Demo

Laravel Auto-Link library

I'm looking for a travel auto-link detection.
I'm trying to make a social media website and when my users post URLs I need it so like shows instead of just normal text.
Try Autologin for Laravel by dwightwatson, which provides you to generate URLs that will provide automatic login to your application and then redirect to the appropriate location
As far as I know, there's no equivalent in the Laravel's core for the auto_link() funtion helper from Code Igniter (assuming you are refering to the CI version).
Anyway, it's very simple to grab that code and use it in Laravel for a quick an dirty workaround. I just did casually looking for the same issue.
Put in your App directory a container class for your helpers (or any containter for the matter, it's just need to be discovered by the framework), in this case I put a UrlHelpers.php file. Then, inside of it put this two static functions grabbed for the CI version:
class UrlHelpers
{
static function auto_link($str, $type = 'both', $popup = FALSE)
{
// Find and replace any URLs.
if ($type !== 'email' && preg_match_all('#(\w*://|www\.)[^\s()<>;]+\w#i', $str, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
// Set our target HTML if using popup links.
$target = ($popup) ? ' target="_blank"' : '';
// We process the links in reverse order (last -> first) so that
// the returned string offsets from preg_match_all() are not
// moved as we add more HTML.
foreach (array_reverse($matches) as $match) {
// $match[0] is the matched string/link
// $match[1] is either a protocol prefix or 'www.'
//
// With PREG_OFFSET_CAPTURE, both of the above is an array,
// where the actual value is held in [0] and its offset at the [1] index.
$a = '<a href="' . (strpos($match[1][0], '/') ? '' : 'http://') . $match[0][0] . '"' . $target . '>' . $match[0][0] . '</a>';
$str = substr_replace($str, $a, $match[0][1], strlen($match[0][0]));
}
}
// Find and replace any emails.
if ($type !== 'url' && preg_match_all('#([\w\.\-\+]+#[a-z0-9\-]+\.[a-z0-9\-\.]+[^[:punct:]\s])#i', $str, $matches, PREG_OFFSET_CAPTURE)) {
foreach (array_reverse($matches[0]) as $match) {
if (filter_var($match[0], FILTER_VALIDATE_EMAIL) !== FALSE) {
$str = substr_replace($str, static::safe_mailto($match[0]), $match[1], strlen($match[0]));
}
}
}
return $str;
}
static function safe_mailto($email, $title = '', $attributes = '')
{
$title = (string)$title;
if ($title === '') {
$title = $email;
}
$x = str_split('<a href="mailto:', 1);
for ($i = 0, $l = strlen($email); $i < $l; $i++) {
$x[] = '|' . ord($email[$i]);
}
$x[] = '"';
if ($attributes !== '') {
if (is_array($attributes)) {
foreach ($attributes as $key => $val) {
$x[] = ' ' . $key . '="';
for ($i = 0, $l = strlen($val); $i < $l; $i++) {
$x[] = '|' . ord($val[$i]);
}
$x[] = '"';
}
} else {
for ($i = 0, $l = strlen($attributes); $i < $l; $i++) {
$x[] = $attributes[$i];
}
}
}
$x[] = '>';
$temp = array();
for ($i = 0, $l = strlen($title); $i < $l; $i++) {
$ordinal = ord($title[$i]);
if ($ordinal < 128) {
$x[] = '|' . $ordinal;
} else {
if (count($temp) === 0) {
$count = ($ordinal < 224) ? 2 : 3;
}
$temp[] = $ordinal;
if (count($temp) === $count) {
$number = ($count === 3)
? (($temp[0] % 16) * 4096) + (($temp[1] % 64) * 64) + ($temp[2] % 64)
: (($temp[0] % 32) * 64) + ($temp[1] % 64);
$x[] = '|' . $number;
$count = 1;
$temp = array();
}
}
}
$x[] = '<';
$x[] = '/';
$x[] = 'a';
$x[] = '>';
$x = array_reverse($x);
$output = "<script type=\"text/javascript\">\n"
. "\t//<![CDATA[\n"
. "\tvar l=new Array();\n";
for ($i = 0, $c = count($x); $i < $c; $i++) {
$output .= "\tl[" . $i . "] = '" . $x[$i] . "';\n";
}
$output .= "\n\tfor (var i = l.length-1; i >= 0; i=i-1) {\n"
. "\t\tif (l[i].substring(0, 1) === '|') document.write(\"&#\"+unescape(l[i].substring(1))+\";\");\n"
. "\t\telse document.write(unescape(l[i]));\n"
. "\t}\n"
. "\t//]]>\n"
. '</script>';
return $output;
}
}
The function safe_mailto is used in case there are email links in your string. If you don't need it you are free to modify the code.
Then you could use the helper class like this in any part of your Laravel code as usually (here inside a blade template, but the principle is the same):
<p>{!! \App\Helpers\Helpers::auto_link($string) !!}</p>
Quick and dirty, and It works. Hope to have helped. ¡Good luck!

PHP - string parsing & concatenation problems

Here is the problem : I want to split a string to have the name and the first name, but my two variable are empty and i don't understant why... Can someone help me ? This my code :
$nom_aut1 = "";
$prenom_aut2 = "";
//$auteur1 is already initialized
for ($i = 0; $i < strlen($auteur1); ++$i)
{
if ($auteur1[$i] != ' ') continue;
for ($j = 0; $j < $i; ++$j)
{
$nom_aut1 .= $auteur[$j];
}
for ($j = $i+1; $j < strlen($auteur1); ++$j)
{
$nom_aut1 .= $auteur1[$j];
}
break;
}
echo '"'.$nom_aut1.'.'.$prenom_aut1.'"';
Thank you :)
Do you want to split a name into first and last name based on a space? Why not just do this:
$names = explode(" ",$name);
If $name = "Hello World"
$names will be an array such that
$names[0] = "Hello"
$names[1] = "World"
This way, if there is a middle name, you can get that as well.
You can do it this way:
$names = explode(" ",$name);
if (count($names) == 1) //only first name
{
$first = $names[0];
$last = "";
}
else if (count($names) == 2) //only first and last name
{
$first = $names[0];
$last = $names[1];
}
else //one or more middle names were provided
{
$first = $names[0];
$last = $names[count($names)-1];
for($i=1;$i<count($names)-1;$i++)
$middle .= $names[$i] . ' ';
$middle = trim($middle);
}
So, if $name = "Hello Foo Bar World"
$first = "Hello"
$last = "World"
$middle = "Foo Bar"
If the letter is not equal to ' ' it continue the loop and does not execute the 2 for loops.
But you are looking for the explode function in PHP:
<?php
$names = explode(' ', $name);
$prenom = $names[0];
$nom = $names[1];
?>
First of all, double check all your variable names.
You are saying:
$nom_aut1 = "";
$prenom_aut2 = "";
You are not using $prenom_aut2 anywhere in your code and then you are echoing:
echo '"'.$nom_aut1.'.'.$prenom_aut1.'"';
In answer to your specific question, you are declaring, populating and echoing different variables.
Another way to explode and manipulate this way!.
list($first_name, $last_name) = explode(" ", $name);
echo $first_name;
echo $last_name;

Walk array recursively and print the path of the walk

Can someone help me with some code or instructions on how to walk recursively an array and when reaching the last element print the full path to it? A simple echo will work because I will adapt the code to some other function I'm developing.
The function doesn't need to figure the array dimension because this param will be passed:
Example:
$depth = 8;
$array[1][3][5][6][9][5][8][9];
When function reachs the 8th element it print all the path to it:
//print path
'1 -> 3 -> 5 -> 6 -> 9 -> 5 -> 8 -> 9'
As I said, only printing in this format will work cause I will implement the code into some other function.
array keys can have the same value. Obviously not the same value in the same sequence for the entire arary.
Updated:
Walk recursively function:
$someArray[1][2][3] = 'end';
$someArray[1][2][6] = 'end';
$someArray[1][3][6] = 'end';
$someArray[4][3][7] = 'end';
function listArrayRecursive(&$array_name, $ident = 0){
if (is_array($array_name)){
foreach ($array_name as $k => &$v){
if (is_array($v)){
for ($i=0; $i < $ident * 10; $i++){ echo " "; }
echo $k . " : " . "<br>";
listArrayRecursive($v, $ident + 1);
}else{
for ($i=0; $i < $ident * 10; $i++){ echo " "; }
echo $k . " : " . $v . "<br>";
}
}
}else{
echo "Variable = " . $array_name;
}
}
listArrayRecursive($someArray);
Will print:
1 :
2 :
3 : end
6 : end
3 :
6 : end
4 :
3 :
7 : end
Now, how can I also print the path of the array everytime it reaches the end? For example:
1 :
2 :
3 : end : path -> 1,2,3
6 : end : path -> 1,2,6
3 :
6 : end : path -> 1,3,6
4 :
3 :
7 : end : path -> 4,3,7
EDITED CODE ADDING A THIRD PARAM TO RECORD THE PATH:
$someArray[1][2][3] = 'end';
$someArray[1][2][6] = 'end';
$someArray[1][3][6] = 'end';
$someArray[4][3][7] = 'end';
$someArray[3][2] = 'end';
function listArrayRecursive(&$array_name, $ident = 0, $path = null){
foreach ($array_name as $k => &$v){
if (is_array($v)){
for ($i=0; $i < $ident * 10; $i++){ echo " "; }
echo $k . " : " . "<br>";
$path .= $k . ', ';
listArrayRecursive($v, $ident + 1, $path);
}else{
for ($i=0; $i < $ident * 10; $i++){ echo " "; }
echo $k . " : " . $v . ' - path -> ' . $path . "<br>";
}
}
}
listArrayRecursive($someArray);
Will print:
1 :
2 :
3 : end - path -> 1, 2,
6 : end - path -> 1, 2,
3 :
6 : end - path -> 1, 2, 3,
4 :
3 :
7 : end - path -> 1, 4, 3,
3 :
2 : end - path -> 1, 4, 3,
You could employ a RecursiveIteratorIterator (docs) to take the hard work out of recursing through the arrays.
function listArrayRecursive($someArray) {
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($someArray), RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterator as $k => $v) {
$indent = str_repeat(' ', 10 * $iterator->getDepth());
// Not at end: show key only
if ($iterator->hasChildren()) {
echo "$indent$k :<br>";
// At end: show key, value and path
} else {
for ($p = array(), $i = 0, $z = $iterator->getDepth(); $i <= $z; $i++) {
$p[] = $iterator->getSubIterator($i)->key();
}
$path = implode(',', $p);
echo "$indent$k : $v : path -> $path<br>";
}
}
}
This example is to give you idea, not to solve the actual task.
function recursiveSearch($array,$search){
foreach($array as $key=>$val){
if($val==$search)return $key;
$x=recursiveSearch($array[$key],$search);
if($x)return $key.' -> '.$x;
}
}
echo recursiveSearch($array,'search');
If no match is found, null is returned.
$a= array(1,2,3,4,5,6);
$val = end($a);
print_array($a,$val);
function print_array(&$arr, $val)
{
if ($val === false)
return;
$curr = prev($arr);
print_array($arr,$curr);
echo $val;
}
I just wrote a function that makes recursive looping a bit easier:
Similar to array_walk_recursive but with some extra functionality
public static function walk($array, $callback, $custom = null, $recursive = false, $info = [])
{
$r = $recursive;
if (gettype($r) === 'integer') {
$r--;
}
$info['depth'] = empty($info)?1:$info['depth'] + 1;
$info['count'] = count($array);
$info['i'] = 1;
foreach($array as $k => $v) {
if (is_array($v) && $r > 0) {
$array[$k] = static::walk($v, $callback, $custom, $r, $info);
} else {
$array[$k] = $callback($v, $k, $custom, $info);
}
$info['i'] ++;
}
return $array;
}
public static function walkable($v, $k, $custom, $info)
{
if (is_string($v)) {
return $v." [ custom: {$custom['key']} ] [ level: ".$info['depth'].' | No '.$info['i'].' of '.$info['count']." ]";
}
return $v;
}
Called like so:
$result = Namespace\ClassName::walk($array, ['Namespace\ClassName', 'walkable'], ['key'=>'value'], true);
Setting recursive to false will only evaluate the first level.
Setting recursive to true will cause it to traverse the entire array.
Setting recursive to an integer will cause it to only traverse to that depth.
Walkable functions can be referenced or passed to callback as anonymous function.
(expects: value, key, custom, info)
The returned value replace the current value.
Custom data can be passed and some additional info is provided for you.
You can expand on the walk function if you need additional info.
I had similar problem. Here is a Depth-First Search-ish solution(no path depth included, it reaches until the very end of the array). Comment the 'if' statement if u don't want to include the value:
$output = array();
retrievePath($someArray, $output);
function retrievePath($someArray, array &$pathKeeper)
{
if(!is_array($someArray)){ // $someArray == "end"
$element = array_pop($pathKeeper) ?? '';// if the array is empty pop returns null, we don't want that
array_push($pathKeeper, $element . '->'. $someArray);
} else{
end($someArray);//we want to get the last element from the array so we move the internal pointer to it's end
$endElKey = key($someArray);//take the key where the pointer is
reset($someArray);
foreach($someArray as $key=>$value){
$element = array_pop($pathKeeper);
array_push($pathKeeper, $element === null ? $key : $element . '->' . $key);// we don't want '->' at the beginning
retrievePath($value, $pathKeeper);
if($key != $endElKey) //we check whether this is not the last loop
array_push($pathKeeper, $element);
}
}
}
<?php
function printListRecursive($a, $var='', $i = 0) {
if (!is_array($a)) {
$var .= $a;
return $var;
}
$string = "";
foreach ($a as $k => $value) {
$string .= str_repeat(" ", $i) .' - '. $k . ':';
if (!is_array($value)) {
$string .= $value . '<br />';
} else {
$string .= '<br />';
$string .= printListRecursive($value, $var, $i + 1);
}
}
return $string;
}
$test_array = [
'America' => [
'Argentina' => 'Buenos Aires',
'Peru' => 'Lima'
],
'Europe' => [
'Ireland' => 'Dublin',
'France' => 'Paris',
'Italy' => 'Rome'
]
];
$result = printListRecursive($test_array);
echo $result;
?>
Check code here
I came up with the following function based on #salathe's one. It returns an array where each element is an array containing the leaf at index 0 and the array of the path keys at index 1:
function loosenMultiDimensionalArrayPathForEachVal($array) {
$iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($array), \RecursiveIteratorIterator::SELF_FIRST);
$iterator->rewind();
$res = [];
foreach ($iterator as $v) {
$depth = $iterator->getDepth();
for ($path = array(), $i = 0, $z = $depth; $i <= $z; $i++) {
$path[] = $iterator->getSubIterator($i)->key();
}
$leaf = $array;
foreach ($path as $pathKey) {
$leaf = $leaf[$pathKey];
}
if (!is_array($leaf)) {
$res[] = [
$v,
$path
];
}
}
return $res;
}
The main reason I implemented this one is that $iterator->hasChildren() returns true if the current iterated leaf is an object. Therefore, I wouldn't be able to get the path of it that way.
I found this solution, which also keeps into account if elements of the structure are arrays:
$file_contents=file_get_contents("data.json");
$json_dump=json_decode($file_contents);
printPath($json_dump, '', "" ,"");
function printPath($the_array, $path, $prevType) {
// Parse all elements of a structure
// and print full PHP path to each one.
foreach($the_array as $key => $value) {
if(is_array($value)) {
// Array element cannot be directly printed: process its items as objects:
printPath($value, $path . $key , "array");
} else {
if (!is_object($value)) { // If the element is not an object, it can be printed (it's a leaf)
if(is_string($value)) {
$finalValue = '"' . $value . '"';
} else {
$finalValue = $value;
}
if($prevType == "array") {
// If array element, add index in square brackets
echo($path . "[" . $key . "] = " . $finalValue . "<br>");
} else {
echo($path . $key . " = " . $finalValue . "<br>");
}
} else { // else store partial path and iterate:
if($prevType == "array") {
// Path of array element must contain element index:
printPath($value, $path . "[" . $key . "]->" , "dummy");
} else {
printPath($value, $path . $key . "->", "dummy");
}
}
}
}
}
Example output:
status->connections->DSS-25->band = "X"
status->connections->DSS-25->endAt = "2019-11-20T20:40:00.000Z"
status->connections->DSS-25->startAt = "2019-11-20T12:40:00.000Z"
geometry[0]->obs[0]->name = "UDSC64"
geometry[0]->obs[0]->hayabusa2->azm = 90.34
geometry[0]->obs[0]->hayabusa2->alt = -20.51
In case anybody is interested, here it is the port to Javascript:
function iterate(obj, stack, prevType) {
for (var property in obj) {
if ( Array.isArray(obj[property]) ) {
//console.log(property , "(L=" + obj[property].length + ") is an array with parent ", prevType, stack);
iterate(obj[property], stack + property , "array");
} else {
if ((typeof obj[property] != "string") && (typeof obj[property] != "number")) {
if(prevType == "array") {
//console.log(stack + "[" + property + "] is an object, item of " , prevType, stack);
iterate(obj[property], stack + "[" +property + "]." , "object");
} else {
//console.log(stack + property , "is " , typeof obj[property] , " with parent ", prevType, stack );
iterate(obj[property], stack + property + ".", "object");
}
} else {
if(prevType == "array") {
console.log(stack + "[" + property + "] = "+ obj[property]);
} else {
console.log(stack + property , " = " , obj[property] );
}
}
}
}
}
iterate(object, '', "File")
You can add a third parameter which holds the actual path as String. At the end you can output it then.

Php Booleans not working correctly?

I have the following code, I seem to be having problems with booleans in php, when ever i dump out the value of bCreatedEvent it is just empty, what am i doing wrong and I'm using booleans wrong? It also fails my logic check so i can redirect at the bottom. I'm fairly new to php, but thought most of this should work similar to c/c++.
$dbTheatreCMS = new TheatreCMSDB();
$iEventID = $dbTheatreCMS->InsertNewEvent($sTitle, $sCompany, $iCreateID, $sNotes, $sPrePrice, $sRegPrice);
$bEventCreated = False;
echo "bEventCreated1 = " . $bEventCreated . "<br/>";
$bEventInfoInserted = True;
$bEventRolesInserted = True;
if ($iEventID > 0)
{
$bEventCreated = true;
if (isset($_POST["Venues"], $_POST["EventDates"]))
{
$aiVenueIDs = $_POST["Venues"];
$adtEvents = $_POST["EventDates"];
if (count($adtEvents) == count($aiVenueIDs)) // These should be the same length
{
for ($i = 0; $i < count($adtEvents); $i++)
{
$bEventInfoInserted &= ($dbTheatreCMS->InsertNewEventInfo($iEventID, $aiVenueIDs[$i],$adtEvents[$i]) > 0) ? true :false;
}
}
}
if (isset($_POST["Troupers"], $_POST["Roles"]))
{
$trouperIDs = $_POST["Troupers"];
$roles = $_POST["Roles"];
if (count($trouperIDs) == count($roles))
{
for ($i = 0; $i < count($trouperIDs); $i++)
{
$bEventInfoInserted &= ($dbTheatreCMS->InsertNewTroupeInfo($iEventID, $trouperIDs[$i],$roles[$i]) > 0)? true:false;
}
}
}
}
echo "bEventCreated = " . $bEventCreated . "<br/>";
echo "bEventInfoInserted = " . $bEventInfoInserted . "<br/>";
echo "bEventRolesInserted = " . $bEventRolesInserted . "<br/>";
$bEventCreated = $bEventCreated & $bEventInfoInserted & $bEventRolesInserted;
echo "$bEventCreated = " . $bEventCreated . "<br/>";
if($bEventCreated == True)
{
echo "<script type='text/javascript'>window.localStorage.href = 'some page.php';</script>";
}
output
bEventCreated1 =
bEventCreated =
bEventInfoInserted = 1
bEventRolesInserted = 1
0 = 0
echo false will look empty use var_dump($bEventCreated)
Also & is a bitwise operator I think you mean &&
$bEventCreated = $bEventCreated & $bEventInfoInserted & $bEventRolesInserted;
Make sure you always use identical or not identical comparison operators when doing a boolean condition:
if($bEventCreated === TRUE)
If a value is false, it will not echo or print a value. See for example:
<?php
$true = true;
$false = false;
echo $true."\n";
echo $false."\n";
var_dump($true)."\n";
var_dump($false);
?>
http://codepad.org/98bR4bfn
There are some quirks with booleans in PHP. This two links may help:
http://pl.php.net/manual/en/language.types.boolean.php
http://pl.php.net/manual/en/language.types.string.php#language.types.string.casting
When you echo a variable it is first converted to a string.
When FALSE or NULL is converted to a string they are converted to an empty string, "". TRUE is converted to "1". Arrays are converted to "Array". Resources are undefined although they are currently converted like "Resource #N". Objects will throw an error if they don't implement __toString().

Categories