Update a string to follow a specific format - php

I have a column in my database that stores a string of numbers, separated by commas.
,,133,,,,444,,,,555,,,,6,
Rules:
The first number in the string is always preceded by 2 commas
There are always 4 commas between the middle numbers
The last number only has 1 comma after it
The example above is how I always want the string to look..
What happens is when some of these numbers are removed the updated string looks like this:
,,31,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,998,,,,476,,,,,
Making it look messy in the database and sometimes causing trouble with the extra commas when I try to output each number
I've been manually updating each value to follow the format I want but I'd like to make a script that runs each night and takes each of these strings and updates them with the correct format following the rules I listed above.
What can I use to format the string to follow the rules above?

You could create a php script that loads the values from the database, manipulate the rows, and store the manipulated values back to the database. I don't know what database and table structure you use, but the manipulation part is simple:
// load the string from the database into the $value variable
$numbers= preg_split("/,+/", $value); // split the string
$numbers= array_filter( $numbers); // remove empty array elements
$newvalue = implode(',,,,', $numbers); // join the array elements to a string separated by ,,,,
$newvalue = ',,' . $newvalue . ','; // add ,, at the beginning and , at the end of the new value
// store $newvalue in the database

Related

Parse PHP array stored as string and concatenate items to string in Power Query

I'm doing my first steps with Power Query in Excel. I have exported some data from PHP to a .csv file and want to import them to an excel sheet. This works great with strings and numbers, but I need an improved Power Query statement to read array data.
The PHP string array looks something like:
a:3:{i:0;s:4:"Text";i:1;s:2:"in";i:2;s:5:"array";}
"a" stands for the array name
"3" is the number of items in array
Within the curly brace {} stands the array with
"i" for the index and
"s" for the length of the item (string)
The strings "Text", "in" and "array" are the items in the array, which I want to parse.
My Idea is to parse the PHP array string to a Power Query list and concatenate the items to a comma separated string.
In the end i want to have this string:
"Text, in, array"
I have tried to remove the a, i, s, ; and the numbers to get something like a json string:
= Text.Remove([PHP-array],{"0".."9"}),...
And then parse with:
Json.Document([JSON-string])
But this seems inelegant and prone to error.
Is there a way to parse the PHP array to a list and than serialize it to a comma separated string?
Edit/Update
A new idea is to extract only the strings between quotes " and merge them. It tried it this way:
Table.TransformColumns(#"Column", {{"function", each Text.BetweenDelimiters(_, """", """"), type text}})
But this works only for the first occurence. I would need to repeat it for each item and separate them with comma. But how to do this? Is there a kind of a loop in Power Query?
In PowerQuery, this works to convert the data from Column1 of Table1 into a new column called Custom
Splits into a list based on "
If the array item contains a ; then convert that to a null
remove all nulls
Recombine remaining list items separated by , (space)
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Custom" = Table.AddColumn(Source, "Custom", each Text.Combine(List.RemoveNulls(List.Transform(Text.Split([Column1], """"), each if not(Text.Contains(_,";")) then _ else null)),", "))
in #"Added Custom"

Stringing together variables, str_replace. Tidier way to do this?

I have a bunch of variables that I want to string together. They all need to be tidied up by removing spaces and commas, and converting to dashes (I'm constructing a URL).
I have a very basic understanding of PHP, but I feel my code below could be tidier and more efficient. Could you point me to some resources or make some suggestions please?
Here's what I have:
$propNum = $prop->Address->Number;
$propStreet = $prop->Address->Street;
$propTown = $prop->Address->Town;
$propPost = $prop->Address->Postcode;
$propFullAdd = array($propNum, $propStreet, $propTown, $propPost);
$propFullAddImp = implode(" ",$propFullAdd);
$propFullAddTidy = str_replace(str_split(' ,'),'-', strtolower($propFullAddImp));
echo $propFullAddTidy;
From the output of your existing code, it seems like you may want an output that looks something like:
12345-example-street-address-example-town-example-postcode
In this case, you could use this solution:
//loop through all the values of $prop->Address
foreach($prop->Address as $value) {
//for each value, replace commas & space with dash
//store altered value in new array `$final_prop`
$final_prop[] = str_replace([' ', ','], '-', $value);
/*
Removing `str_split(' ,')` and subbing an array makes the loop "cheaper" to do,
Because the loop doesn't have to call the `str_split()` function on every iteration.
*/
}
//implode `$final_prop` array to dash separated string
//also lowercase entire string at once (cheaper than doing it in the loop)
$final_prop = strtolower(implode('-', $final_prop));
echo $final_prop;
if you remove the comments, this solution is only 4 lines (instead of 7), and is completely dynamic. This means if you add more values to $prop->Address, you don't have to change anything in this code.
A different method
I feel like this would usually be handled by using http_build_query(), which converts an array into a proper URL-encoded query string. This means that each value in the array would be passed as it's own variable in the URL query.
First, $propFullAdd is not necessary (in fact, it may be detrimental), $prop->Address already contains the exact same array. Recreating the array like this completely removes the ability to tell which value goes to which key, which could be problematic.
This means that you can simplify your entire code by replacing it with this:
echo http_build_query($prop->Address);
Which outputs something like this:
Number=12345&Street=Example+Street+Address&Town=Example+Town&Postcode=Example+Postcode

keep adding up code from database

# Check arrary not empty
if (!empty($results)) {
$this->code($results);
// got the mail code from database
// which is PG-000001
// how do i add , like something PG-000001 ++
}
this will return a result from database , my intention is to keep adding up the code that return from my database and the update back to the database.
now it was return PG-000001, how do i make it add up and be like PG-000002 and then update it and next time it will be PG-000002 and up to 000003 and so on.
how do i add up the text PG-000001?
If all of your codes look like this, then your really shouldn’t store them that way. It appears that the PG- at the beginning is just a prefix. If you store the actual value as an integer, you can increment as much as you like.
Anyway, the solution to your question is that you will need to
split the string
increment the second part
zero-pad the second part
combine again
Here is a little test script:
$test='PG-000001';
$pattern='/(.*-)(\d+)/';
preg_match($pattern,$test,$matches);
list(,$prefix,$value)=$matches;
$value=sprintf('%06d',$value+1);
$test="$prefix$value";
print $test;
Translation:
/(.*-)(\d+)/ is the pattern that will split the string into the prefix & numeral
preg_match applies the pattern and returns the result into the array $matches.
$matches has the original string, and then the two matches
list() copies elements of the array into variables. The leading comma skips the first element
sprintf formats the data. In this case, the code 0-pads to 6 digits
the double-quoted string is a simple way of recombining your data.

Change URL argument separator

First I have to say that I am a total newbie, I have literally 0 experience with PHP.
Here is my problem. I have a sensor, that sends data into mysql database in following form:
http://192.168.1.2/add.php?i=mit=0106,22:5113/07/2016,liv=175cm,livp=000%,b=12.0V,t=36;
Now I am able to display this in my mysql table:
"mit=0106,22:5113/07/2016,liv=175cm,livp=000%,b=12.0V,t=36;"
but I would like to display each argument separately.
Do you know how to change the separator from "&" to ","?
Ideal solution would be to change the url command to this form:
http://192.168.1.2/add.php?i=mit=0106&22:5113/07/2016&liv=175cm&livp=000%&b=12.0V&t=36;
but unfortunately I can reprogramm the sensor, so I need to change the separator from "&" to ",".
arg_separator.input is the configuration directive you are looking for:
arg_separator.input string
List of separator(s) used by PHP to parse input URLs into variables.
Note:
Every character in this directive is considered as separator!
Be aware the setting mode is PHP_INI_PERDIR, meaning it "can be set in php.ini, .htaccess, httpd.conf or .user.ini (since PHP 5.3)" (http://php.net/manual/en/configuration.changes.modes.php)
If you can't change this setting, you might look at the query string as a whole (see $_SERVER variable), and split it at the comma yourself, using explode or something like that.
If I got it right, you have to store all name=value pairs from that string into separate columns in database table.
In this case you can't use explode() because of first value that contains comma.
Assuming that you already have created columns called mit, liv, livp, b and t with required data-type, and your string is double-checked before it goes to database to avoid SQL injections, you can do something like this:
# your input string
$input = "mit=0106,22:5113/07/2016,liv=175cm,livp=000%,b=12.0V,t=36;";
# loop through it and determine all name=value pairs
while (strlen($input)>2) {
preg_match ('/([a-z]+)\=(.*?)(?:,[a-z]+=|;)/', $input, $m);
# store names here
$d1[] = "'{$m[1]}'";
# and values here
$d2[] = "'{$m[2]}'";
$input = substr($input, strlen($m[1]) + strlen($m[2]) + 2);
}
# join arrays into string
$d1 = join(",", $d1);
$d2 = join(",", $d2);
# and put them into query
$sql = "INSERT INTO mytable ($d1) VALUES ($d2);";
echo $sql;
This will print out a query like this
INSERT INTO mytable ('mit','liv','livp','b','t')
VALUES ('0106,22:5113/07/2016','175cm','000%','12.0V','36');
How that while loop works?
It uses $input as argument and look for name=value followed by another name= (for inner pairs) or ; (for last pair) to determine its end. Than it extracts name into separate array d1 and value into another array called d2. Removes first match from the beginning of the string and takes another turn in loop until the $input string is empty. Course, elements into those two arrays are stored surrounded with single quotes for later use in query.
At the end, I joined both arrays (separately) with comma between elements and put them into query string called $sql.
Please note (again) that it's dangerous to send data this way directly from URI's GET parameter into database with no previous validation of data.
Not sure what you mean exactly but you can use str_replace() to help you or possibly you can convert this into an array using explode() then do what you need to do with the data and put it back into a string using implode().
edit: thanks, fixed the mixup.
echo "http://192.168.1.2/add.php?i=" . str_replace(",","&","mit=0106,22:5113/07/2016,liv=175cm,livp=000%,b=12.0V,t=36;");

Most efficient PHP str_replace on array if row only has 5% chance of containing target?

I have a 15,000 row PHP array. I need to iterate through each row to generate a 15,000 row Javascript array. Each row of the PHP array has a 5% chance of containing one or more HTML special characters like ó that I need to replace with the equivalent javascript hex. There are about 50 HTML special characters I have to look out for and replace, so I'd use str_replace(array_of_HTML_targets, array_of_hex_replacements, haystack). Is it more efficient to:
Go through each line of the PHP array, search for an ampersand, and if one exists do the search and replace (considering this will apply for only 5% of the rows)
Execute the search and replace on the entire array
Concatenate the array into one giant string and execute the search and replace on the giant string
Other idea? Please specify
Btw, reason for 15,000 PHP array is this is a data visualization app.
Since you already need to dump your PHP data into a string (probably JSON), you might as well work on the final string, like so:
$json = json_encode($your_php_array);
$unhtmlref = preg_replace_callback("/&#(x[0-9a-f]+|\d+);/",function($m) {
if( $m[1][0] == "x") $m[1] = substr($m[1],1);
else $m[1] = dechex($m[1]);
return sprintf("\\u%04s",$m[1]);
},$json);
This is safe, because HTML character codes don't have any special meaning in a JSON string.
That said, I have a function in my JavaScript "utility belt" that does something similar:
function unHTMLref(str) {
// take a string and return it, with all HTML character codes parsed
var div = document.createElement('div');
div.innerHTML = str.replace(/</g,"<");
return div.firstChild.nodeValue;
}
So basically you can either parse before, or after. Personally, I'd prefer "after" because it shifts some of the "grunt" work to the browser, allowing the server to do more important things.

Categories