properly render an array of numeric values, not an array with strings - php

I have this code in my symfony controller:
$em=$this->getDoctrine()->getManager();
$queryIndex = $em->createQuery( 'SELECT g.index
FROM MySpaceMyBundle:Graphique g');
$result = $queryIndex->getArrayResult();
$arrayResult = array_map('current', $result);
var_dump($arrayResult);
return $this->render('MySpaceMyBundle:MyFolder:myTemplate.html.twig');
With my var_dump, I have this result:
array (size=10)
0 => string '1700.000' (length=8)
1 => string '1200.000' (length=8)
2 => string '1200.000' (length=8)
3 => string '1304.000' (length=8)
4 => string '1800.000' (length=8)
5 => string '2012.000' (length=8)
6 => string '2048.000' (length=8)
7 => string '1048.000' (length=8)
8 => string '3000.000' (length=8)
9 => string '5421.000' (length=8)
But for the obHighchartBundle (using highchart.js) the result I want is:
[1700,1200,1200,1304,1800,2012,2048,1048,3000,5421]
How can I proceed?
Note that I need to pass a numeric array (the values are decimal types in my database), not array with strings.

Like this?
$result = [];
foreach ($arrayResult as $value) {
$result[] = (int) $value
}
var_dump($result);

You can use a tiny tips like array_walk function to cast your values as float to prevent highchart issue. See the documentation for this function:
http://php.net/manual/fr/function.array-walk.php
Here an example of the tiny function :
<?php
function forceFloat (&$aItems) {
$aItems = (float) $aItems;
}
$arrayResult = array("1.00","4.55","39494");
var_dump($arrayResult);
array_walk($arrayResult, 'forceFloat');
var_dump($arrayResult);
?>
The output :
array(3) {
[0]=>
string(4) "1.00"
[1]=>
string(4) "4.55"
[2]=>
string(5) "39494"
}
array(3) {
[0]=>
float(1)
[1]=>
float(4.55)
[2]=>
float(39494)
}
Best Regards,
TGA

Related

Custom order array in PHP

I got this array:
$array = array('E1211','E2172','E2181','E233','E241','E286');
And I need to order first by first number-letter, i.e. E1, E2, E3, E4... followed by ordered numbers from lowest to highest.
Desired order would be: E1211, E233, E241, E286, E2172, E2181
If i do sort($array); the order will will be: "E1211", "E2172", "E2181", "E233", "E241" "E286".
If i do natsort($array); it will order by numbers from lowest to higest: "E233", "E241", "E286", "E1211", "E2172", "E2181"
Use usort() with a custom comparison function to split the strings and compare the portions.
<?php
$array = array('E1211','E2172','E2181','E233','E241','E286');
usort($array, function($a, $b){
$pfxA = substr($a,0,2); // Get the first two characters of each string
$pfxB = substr($b,0,2);
if ( $pfxA !== $pfxB) {return $pfxA<=>$pfxB;} // If they're not equal, return the spaceship comparison
return (int)substr($a,2)<=>(int)substr($b,2); // Prefixes are equal. Convert the rest to integers and return the spaceship comparison.
});
var_dump($array);
Output:
array(6) {
[0]=>
string(5) "E1211"
[1]=>
string(4) "E233"
[2]=>
string(4) "E241"
[3]=>
string(4) "E286"
[4]=>
string(5) "E2172"
[5]=>
string(5) "E2181"
}
See https://3v4l.org/5qts5
Actually what you want to do is mixing sorting with your own pattern with natsort(). I doubt if it can be accomplished by some oneliner, however it can be done with simple iteration in separate steps, that code does what I think you want (input data modified for better readibility).
<?php
$array = ['E3123', 'E1211', 'E2181', 'E241', 'E286', 'E2172', 'E233'];
$newArray = [];
$finalArray=[];
// Put it into associative array with required keys (two first chars)
foreach ($array as $item) {
$key = substr($item, 0, 2);
$newArray[$key][] = $item;
}
// sort new array by key (two first chars)
ksort($newArray);
// sort each subarray in natural order and put it to final array
foreach ($newArray as $key => $newItem) {
natsort($newArray[$key]);
$finalArray = array_merge($finalArray, $newArray[$key]);
}
// just check
var_dump($finalArray);
Result:
array (size=7)
0 => string 'E1211' (length=5)
1 => string 'E233' (length=4)
2 => string 'E241' (length=4)
3 => string 'E286' (length=4)
4 => string 'E2172' (length=5)
5 => string 'E2181' (length=5)
6 => string 'E3123' (length=5)

Select certain data in PHP Array

I get the following output when using this line of code var_dump($ticket->find()); How would I access only the identifiers throughout ALL objects?
I tried var_dump($ticket->find()->identifier); but it returned null.
array (size=2)
0 =>
object(stdClass)[9]
public 'tid' => string '1' (length=1)
public 'uid' => string '22' (length=2)
public 'subject' => string 'iPhone 8' (length=8)
public 'issue' => string 'iPhone 8 screen replacement' (length=27)
public 'device' => string 'iPhone 8' (length=8)
public 'created' => string '2017-05-25 00:01:11' (length=19)
public 'identifier' => string '29cd54bf' (length=8)
public 'status' => string 'New' (length=3)
public 'tech' => string 'None' (length=4)
1 =>
object(stdClass)[11]
public 'tid' => string '2' (length=1)
public 'uid' => string '22' (length=2)
public 'subject' => string 'iPhone 7' (length=8)
public 'issue' => string 'iPhone 7 screen replacement' (length=27)
public 'device' => string 'iPhone 7' (length=8)
public 'created' => string '2017-05-25 00:27:42' (length=19)
public 'identifier' => string 'b47f2c82' (length=8)
public 'status' => string 'New' (length=3)
public 'tech' => string 'None' (length=4)
You could use array_map to select the properties that you need from each item in the array returned by find:
$filteredFields = array_map(function ($item) {
// Return whatever properties you want here:
return [$item->tid, $item->$uid, $item->issue];
}, $ticket->find());
$filteredFields will be an array of arrays:
array(2) {
[0]=> array(3) {
[0]=> string(1) "1"
[1]=> string(2) "22"
[2]=> string(8) "iPhone 7"
}
[1]=> array(3) {
[0]=> string(1) "2"
[1]=> string(2) "22"
[2]=> string(8) "iPhone 7"
}
}
If you just need one of the properties, it may be easier to use array_column:
$subjectFields = array_column($ticket->find(), "subject");
This will return something that looks like this:
array(2) {
[0]=> string(8) "iPhone 8"
[1]=> string(8) "iPhone 7"
}
You can also get an associative array indicating which field to use as the key with the third parameter:
$subjectsByTid = array_column($ticket->find(), "subject", "tid");
This will return:
array(2) {
["1"]=> string(8) "iPhone 8"
["2"]=> string(8) "iPhone 7"
}

PDO Fetch data returns array of string

I am trying to get data from a MySQL database with PDO but unfortunately PDO returns the result as an array of strings. I want to keep the native MySQL data types in the result array.
I have tried setting PDO::ATTR_DEFAULT_FETCH_MODE to both PDO::FETCH_ASSOC AND PDO::FETCH_OBJ but it was still returning INT data as string.
Here is the result of dump:
array (size=1)
0 =>
object(stdClass)[27]
public 'id' => string '3' (length=1)
public 'avatar' => string '' (length=0)
public 'fullName' => string 'Mikheil Janiashvili' (length=19)
public 'email' => string 'xxxxx#yyyyy.com' (length=17)
public 'phone' => string '23 3537 20 03544' (length=12)
public 'educationGE' => string '' (length=0)
public 'educationEN' => string '' (length=0)
public 'educationRU' => string '' (length=0)
public 'experienceGE' => string '' (length=0)
public 'experienceEN' => string '' (length=0)
public 'experienceRU' => string '' (length=0)
public 'descriptionGE' => string '' (length=0)
public 'descriptionEN' => string '' (length=0)
public 'descriptionRU' => string '' (length=0)
When you instantiate your PDO object, you need to tell it to use MySQL's native prepared queries:
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
Assuming you're using PHP >= 5.3 you will be using the mysqlnd library, which can return proper data types from prepared queries.
Example:
$ php -a
Interactive shell
php > $db = PDO("mysql:host=localhost;dbname=test", "test", "");
php > $res = $db->query("SELECT 1, PI()");
php > var_dump($res->fetch());
array(4) {
[1]=>
string(1) "1"
[2]=>
string(1) "1"
["PI()"]=>
string(8) "3.141593"
[3]=>
string(8) "3.141593"
}
php > $db = PDO("mysql:host=localhost;dbname=test", "test", "", [PDO::ATTR_EMULATE_PREPARES=>false]);
php > $res = $db->query("SELECT 1, PI()");
php > var_dump($res->fetch());
array(4) {
[1]=>
int(1)
[2]=>
int(1)
["PI()"]=>
float(3.1415926535898)
[3]=>
float(3.1415926535898)
}
php >

Create php array from strings that contains bracket literals

I have a number of strings, that contain the bracket literals:
0 => string '[139432,97]' (length=18)
1 => string '[139440,99]' (length=18)
I need to create string arrays of [139432,97] and [139440,99].
I've tried using json_decode(), but while it works, it creates arrays as float or int using the above data, however I want them as strings.
array (size=2)
0 => float 139432
1 => int 97
array (size=2)
0 => float 139440
1 => int 97
You can put double quotes around the values e.g.
0 => string '["139432","97"]' (length=22)
1 => string '["139440","99"]' (length=22)
This way when you json_decode they should be strings.
Edit:
OK I thought you could control the input - if not then a simple trim and explode could do:
explode(',', trim('[139432,97]', '[]'));
array(2) {
[0]=>
string(6) "139432"
[1]=>
string(2) "97"
}
Is that enough?
Just combining what you already now (json_decode) and what #AlixAxel suggested here you can extract those values to string link:
$subject = '[139432,97]';
$convertedToArrayOfStrings = array_map('strval', json_decode($subject));
or
$convertedToArrayOfString = array_map(function($item){return (string) $item;}, json_decode($subject));
for better performance, see the comment bellow please :)
Why not try with loop and use explode function:
$array = array('139432,97', '139440,99');
$finalArray = array();
$i = 0;
foreach ($array as $arr) {
$explode = explode(",", $arr);
$j = 0;
foreach ($explode as $exp) {
$finalArray[$i][$j] = (int)$exp;
$j++;
}
$i++;
}

how to use markdown parsing technique in php to make separate automated process

I want to develop website with slight automated process or header, menu, navigation bar, footer etc, which uses markdown technique.
for example a navigationbar.md will contain only link text and link address, i want get those details individually (link and text without parsed html format) into variables or parameters in php.
* [Dog][0]
* [German Shepherd][1]
* [Belgian Shepherd][2]
* [Malinois][3]
* [Groenendael][4]
* [Tervuren][5]
* [Cat][6]
* [Siberian][7]
* [Siamese][8]
[0]:(http://google.com)
[1]:(http://google.com)
[2]:(http://google.com)
[3]:(http://google.com)
[4]:(http://google.com)
[5]:(http://google.com)
[6]:(http://google.com)
[7]:(http://google.com)
[8]:(http://google.com)
if don't need any html here id want want nested array contain link text and link address
this structure of markdown will create html output as follow
but i need those list as nested array to perform defined tasks.
let me know if this works.. is their any chance for it
expected output
array (size=9)
0 =>
array (size=2)
0 => string 'Dog' (length=3)
1 => string 'http://google.com' (length=17)
1 =>
array (size=2)
0 => string 'German Shepherd' (length=15)
1 => string 'http://yahoo.com' (length=16)
2 =>
array (size=2)
0 => string 'Belgian Shepherd' (length=16)
1 => string 'http://duckduckgo.com' (length=21)
2 =>
array (size=2)
0 => string 'Malinois' (length=8)
1 => string 'http://amazon.com' (length=17)
2 =>
array (size=2)
0 => string 'Groenendael' (length=11)
1 => string 'http://metallica.com' (length=20)
3 =>
array (size=2)
0 => string 'Tervuren' (length=8)
1 => string 'http://microsoft.com' (length=20)
3 =>
array (size=2)
0 => string 'Cat' (length=3)
1 => string 'http://ibm.com' (length=14)
2 =>
array (size=2)
0 => string 'Siberian' (length=8)
1 => string 'http://apple.com' (length=16)
3 =>
array (size=2)
0 => string 'Siamese' (length=7)
1 => string 'http://stackoverflow.com' (length=24)
This should work. I have provided all the explanation in the comments in the code. This works -
/**
This function takes a strings- $text and $links_text.
For each text value that matches the regular expression, the link
from the $links_text is extracted and given as output.
This returns an array consisting of the text mapped to their links.
It will return a single array if there only single text value, and
a nested array if more than one text is found.
Eg:
INPUT:
var_dump(text_link_map("* [Dog][0]", "[0]:(http://google.com)[1]:(http://yahoo.com)"));
OUTPUT:
array
0 => string 'Dog' (length=3)
1 => string 'http://google.com' (length=17)
*/
function text_link_map($text, $links_text){
$regex= "/\*\s+\[([a-zA-Z0-9\-\_ ]+)\]\[([0-9]+)\]/";
if(preg_match_all($regex, $text, $matches)){
$link_arr = Array();
/*
For each of those indices, find the appropriate link.
*/
foreach($matches[2] as $link_index){
$links = Array();
$link_regex = "/\[".$link_index."\]\:\((.*?)\)/";
if(preg_match($link_regex,$links_text,$links)){
$link_arr[] = $links[1];
}
}
if(count($matches[1]) == 1){
return Array($matches[1][0], $link_arr[0]);
}else{
$text_link = array_map(null, $matches[1], $link_arr);
return $text_link;
}
}else{
return null;
}
}
/**
Function that calls recursive index, and returns it's output.
This is is needed to pass initial values to recursive_index.
*/
function indent_text($text_lines, $links){
$i = 0;
return recursive_index($i, 0, $text_lines, $links);
}
/**
This function creates a nested array out of the $text.
Each indent is assumed to be a single Tab.It is dictated by the
$indent_symbol variable.
This function recursively calls itself when it needs to go from
one level to another.
*/
function recursive_index(&$index, $curr_level, $text, $links){
$indent_symbol = "\t";
$result = Array();
while($index < count($text)){
$line = $text[$index];
$level = strspn($line, $indent_symbol);
if($level == $curr_level){
$result[] = text_link_map($line, $links);
}elseif($level > $curr_level){
$result[count($result) - 1][] = recursive_index($index, $curr_level + 1, $text, $links);
if($index > count($text)){
break;
}else{
$index--;
}
}elseif($level < $curr_level){
break;
}
$index += 1;
}
return $result;
}
$file_name = "navigationbar.md";
$f_contents = file_get_contents($file_name);
//Separate out the text and links part.
//(Assuming the text and the links will always be separated with 2 \r\n)
list($text, $links) = explode("\r\n\r\n", $f_contents);
//Get the nested array.
$formatted_arr = indent_text(explode("\r\n", $text), $links);
var_dump($formatted_arr);
This is the output of the code. It matches your requirements -
/*
OUTPUT
*/
array(4) {
[0]=>
array(2) {
[0]=>
string(3) "Dog"
[1]=>
string(17) "http://google.com"
}
[1]=>
array(2) {
[0]=>
string(15) "German Shepherd"
[1]=>
string(16) "http://yahoo.com"
}
[2]=>
array(3) {
[0]=>
string(16) "Belgian Shepherd"
[1]=>
string(21) "http://duckduckgo.com"
[2]=>
array(3) {
[0]=>
array(2) {
[0]=>
string(8) "Malinois"
[1]=>
string(17) "http://amazon.com"
}
[1]=>
array(2) {
[0]=>
string(11) "Groenendael"
[1]=>
string(20) "http://metallica.com"
}
[2]=>
array(2) {
[0]=>
string(8) "Tervuren"
[1]=>
string(20) "http://microsoft.com"
}
}
}
[3]=>
array(3) {
[0]=>
string(3) "Cat"
[1]=>
string(14) "http://ibm.com"
[2]=>
array(2) {
[0]=>
array(2) {
[0]=>
string(8) "Siberian"
[1]=>
string(16) "http://apple.com"
}
[1]=>
array(2) {
[0]=>
string(7) "Siamese"
[1]=>
string(24) "http://stackoverflow.com"
}
}
}
}
To check, the contents of navigationbar.md is -
* [Dog][0]
* [German Shepherd][1]
* [Belgian Shepherd][2]
* [Malinois][3]
* [Groenendael][4]
* [Tervuren][5]
* [Cat][6]
* [Siberian][7]
* [Siamese][8]
[0]:(http://google.com)
[1]:(http://yahoo.com)
[2]:(http://duckduckgo.com)
[3]:(http://amazon.com)
[4]:(http://metallica.com)
[5]:(http://microsoft.com)
[6]:(http://ibm.com)
[7]:(http://apple.com)
[8]:(http://stackoverflow.com)
Certain assumptions in the code -
The part separating the text(i.e the "* [Dog][0]" part) and the link part(i.e the "[0]:(http://google.com)") are assumed to always be
separated by 2 newlines.
Each parent child differ from a single Tab("\t").
You can test by changing the tabs between text in navigationbar.md.
Hope it helps.

Categories