This is generated through php(just an example. Can be bigger than this.) How do I put this in only one array? So, that i can pass it to view and output in same format.
Name: abc Address: xyz
Title Paid
ABC $100
CDE $200
Name: rrt Address: adf
Title Paid
VDF $140
CEE $400
Name: xcv Address: fdfs
Title Paid
RET $120
SSD $430
$output = array(
array(
'name'=>'abc',
'address'=>'xyz',
'data'=>array(
array(
'title'=>ABC,
'paid'=>100
),
array(
'title'=>CDE,
'paid'=>200
)
)
)
);
Related
How can I convert the data I send with post to php code?
I have 3 select fields. adult, child, baby.
I want to create the following json structure up to the number of rooms when I post. The number of children and babies is not correct by area. How can I do it?
foreach ($this->input->post('adult') as $key => $value) {
$rooms[] = array(
'adult' => $_POST['adult'][$key],
'child' => array(
'child_total' => $_POST['child'][$key],
'child_date' => $_POST['child_date']
),
'baby' => array(
'baby_total' => $_POST['baby'][$key],
'baby_date' => null
)
);
}
I want to this json...
rooms: [
{
adult: 2,
child: [
child_total: 1
child_date: [
"2017-08-10"
],
],
baby: [
baby_total: 1
baby_date: [
"2017-07-01"
],
],
},
{
adult: 1,
child: [
child_total: 2
child_date: [
"2017-08-08",
"2017-08-09"
],
],
baby: [
baby_total: 2
baby_date: [
"2017-06-08",
"2017-05-09"
],
],
}
],
To figure out the data structure needed to make you json encoded string, let's start by defining the objects you're working with. Assuming this is something like a hotel booking system, let's map it out:
A hotel has rooms. They are identified by room number. This can be illustrated in code by $room[$room_number]. Using the room number as the key allows you to uniquely identify a particular room.
Each room has occupants: adults, children, and babies. This can be illustrated in code by
$room[$room_number]['adults']
$room[$room_number]['children']
$room[$room_number]['babies']
The set of babies can be illustrated as $baby[]. We really don't need to identify the baby with a unique identifier other that the index number; we're just interested in the list.
So, let's replace ['babies'] with ['baby'][]
$room[$room_number]['adults']
$room[$room_number]['children']
$room[$room_number]['baby'][]
Each baby has attributes. We're only going to use one, but for the sake of example, let's say we want to record two: birthdate and name. Another way of saying that would be each $baby = array('birthday'=>$birthdate, 'name'=>$name);
This is a little harder to illustrate, since you have to gather all the babies information before you assign it to $room[$room_number]['baby'][]. So I will show it using the index number:
$room[$room_number]['adults']
$room[$room_number]['children']
$room[$room_number]['baby'][0]['birthdate']
$room[$room_number]['baby'][0]['name']
The same functionality is desired for children:
$room[$room_number]['adults']
$room[$room_number]['children'][0]['birthdate']
$room[$room_number]['children'][0]['name']
$room[$room_number]['baby'][0]['birthdate']
$room[$room_number]['baby'][0]['name']
See a pattern? [identifier][attribute][identifier][attribute]
With this data structure, we can build your html inputs, assuming 2 children and 2 babies:
<?php
// assuming room number is 123
$room_number = '123';
?>
<!-- child 1 name -->
<label><input name="room[<?= $room_number ?>]['child'][0]['name']">Child 1 name</label>
<!-- child 1 birthdate -->
<label><input name="room[<?= $room_number ?>]['child'][0]['birthdate']">Child 1 birthdate</label>
<!-- child 2 name -->
<label><input name="room[<?= $room_number ?>]['child'][1]['name']">Child 2 name</label>
<!-- child 2 birthdate -->
<label><input name="room[<?= $room_number ?>]['child'][1]['birthdate']">Child 2 birthdate</label>
When you receive these inputs in your php script, it will already be properly formed as an array (I'm excluding adults and filled in sample values):
php > $room_number='123';
php > $room[$room_number]['child'][0]['birthdate'] = '20010-01-01';
php > $room[$room_number]['child'][0]['name'] ='Junior';
php > $room[$room_number]['child'][1]['birthdate'] = '2019-01-01';
php > $room[$room_number]['child'][1]['name'] = 'Bubba';
php > print_r($room);
Array
(
[123] => Array
(
[child] => Array
(
[0] => Array
(
[birthdate] => 20010-01-01
[name] => Junior
)
[1] => Array
(
[birthdate] => 2019-01-01
[name] => Bubba
)
)
)
)
This can easily be fed into json_encode: print json_encode($room);
However, you might ask what about the counts (totals)?
Those can easily be figured from the array structure, so they don't really need to be included:
php > print count($room[$room_number]['child']);
2
php >
You can use the json_encode function like this:
json_encode(['rooms' => $rooms])
I need to parse a street address in PHP a string that might have abbreviations.
This string comes from a text input.
The fields I need to search are:
street (alphanumeric - might have
building (alphanumeric - might have
number (alphanumeric - might have
area (numeric from 1 to 5)
other (unknown field & used to search in all the above fields in the database)
For example users submits one of this text text:
street Main Road Bulding H7 Number 5 Area 1
st Main Road bldg H7 Nr 5 Ar 5
stMain bldgh7
ar5 unknown other search parameter
street Main Road h7 2b
street main street str main road
The outcome I would like to see as a array:
[street]=>Main Road [building]=>h7 [number]=>5 [area]=>1
[street]=>Main Road [building]=>h7 [number]=>5 [area]=>5
[street]=>Main [building]=>h7
[area]=>5 [other]=>unknown other search parameter
[street]=>Main Road [other]=>h7 2b
[street]=>Main Street&&Main Road
My code so far...but dosen't work with examples 3.,4.,5.,6.:
<?php
//posted address
$address = "str main one bldg 5b other param area 1";
//to replace
$replace = ['street'=>['st','str'],
'building'=>['bldg','bld'],
'number'=>['nr','numb','nmbr']];
//replace
foreach($replace as $field=>$abbrs)
foreach($abbrs as $abbr)
$address = str_replace($abbr.' ',$field.' ',$address);
//fields
$fields = array_keys($replace);
//match
if(preg_match_all('/('.implode('|',array_keys($fields)).')\s+([^\s]+)/si', $address, $matches)) {
//matches
$search = array_combine($matches[1], $matches[2]);
//other
$search['other'] = str_replace($matches[0],"",$address);
}else{
//search in all the fields
$search['other'] = $address;
}
//search
print_r($search);
Code tester: http://ideone.com/j3q4YI
Wow, you've got one hairy mess to clean up. I've toiled for a few hours on this. It works on all of your samples, but I would NOT stake my career on it being perfect on all future cases. There are simply too many variations in addresses. I hope you can understand my process and modify it if/when new samples failed to be captured properly. I'll leave all my debugging comment in place, because I reckon you'll use them for future edits.
$addresses=array(
"street Main Road Bulding H7 Number 5 Area 1",
"st Main Road bldg H7 Nr 5 Ar 5",
"stMain bldgh7",
"ar5 unknown other search parameter",
"street Main Road h7 2b",
"street main street str main road"
);
$regex["area"]="/^(.*?)(ar(?:ea)?\s?)([1-5])(.*?)$/i";
$regex["number"]="/^(.*?)(n(?:umbe)?r\s?)([0-9]+)(.*?)$/i";
$regex["building"]="/^(.*?)(bu?i?ldi?n?g\s?)([^\s]+)(.*?)$/i";
$regex["corner"]="/^(.*?str?(?:eet)?)\s?(str?(?:eet)?.*)$/i"; // 2 streets in string
$regex["street"]="/^(.*?)(str?(?:eet)?\s?)([^\s]*(?:\s?ro?a?d|\s?str?e?e?t?|.*?))(\s?.*?)$/i";
$regex["other"]="/^(.+)$/";
$search=[];
foreach($addresses as $i=>$address){
echo "<br><div><b>$address</b> breakdown:</div>";
foreach($regex as $key=>$rgx){
if(strlen($address)>0){
//echo "<div>addr(",strlen($address),") $address</div>";
if(preg_match($rgx,$address,$matches)){
if($key=="other"){
$search[$i][$key]=$matches[0]; // everything that remains
}elseif($key=="corner"){
$search[$i]["street"]=""; // NOTICE suppression
// loop through both halves of corner address omitting element[0]
foreach(array_diff_key($matches,array('')) as $half){
//echo "half= $half<br>";
if(preg_match($regex["street"],$half,$half_matches)){
//print_r($half_matches);
$search[$i]["street"].=(strlen($search[$i]["street"])>0?"&&":"").ucwords($half_matches[3]);
$address=trim($half_matches[1].$half_matches[4]);
// $matches[2] is the discarded identifier
//echo "<div>$key Found: {$search[$i][$key]}</div>";
//echo "<div>Remaining: $address</div>";
}
}
}else{
$search[$i][$key]=($key=="street"?ucwords($matches[3]):$matches[3]);
$address=trim($matches[1].$matches[4]);
// $matches[2] is the discarded identifier
//echo "<div>$key Found: {$search[$i][$key]}</div>";
//echo "<div>Remaining: $address</div>";
//print_r($matches);
}
}
}else{
break; // address is fully processed
}
}
echo "<pre>";
var_export($search[$i]);
echo "</pre>";
}
The output is an array that satisfies your brief, but the keys are out of order because I captured the address components out of order -- this may not matter to you, so I didn't bother re-sorting it.
street Main Road Bulding H7 Number 5 Area 1 breakdown:
array (
'area' => '1',
'number' => '5',
'building' => 'H7',
'street' => 'Main Road',
)
st Main Road bldg H7 Nr 5 Ar 5 breakdown:
array (
'area' => '5',
'number' => '5',
'building' => 'H7',
'street' => 'Main Road',
)
stMain bldgh7 breakdown:
array (
'building' => 'h7',
'street' => 'Main',
)
ar5 unknown other search parameter breakdown:
array (
'area' => '5',
'other' => 'unknown other search parameter',
)
street Main Road h7 2b breakdown:
array (
'street' => 'Main Road',
'other' => 'h7 2b',
)
street main street str main road breakdown:
array (
'street' => 'Main Street&&Main Road',
)
...boy am I glad this project doesn't belong to me. Good luck!
Thank you for the help! I thought that I should do something like multiple preg_matches.
I just found a PHP extension that does exactly what I want.
The library is PHP Postal (https://github.com/openvenues/php-postal) and requires libpostal. It takes about 15-20 seconds to load the library when you run PHP, after this everything work ok.
Total execution time for parsing: 0.00030-0.00060 seconds.
$parsed = Postal\Parser::parse_address("The Book Club 100-106 Leonard St, Shoreditch, London, Greater London, EC2A 4RH, United Kingdom");
foreach ($parsed as $component) {
echo "{$component['label']}: {$component['value']}\n";
}
Output:
house: the book club
house_number: 100-106
road: leonard st
suburb: shoreditch
city: london
state_district: greater london
postcode: ec2a 4rh
country: united kingdom
All I had to do after this is to replace my labels and format the address.
Hope this will help others, who want to parse a address in PHP.
Essentially, I am trying to format the follow:
I have a series of users, that are part of different communities and each community has a series of tasks to complete BUT some of the tasks within the community are only related to some users. Like so:
Community 1
Members: Joe, James
Tasks: Task 1, Task 2, Task 3
Assigned: Task 1 -> Joe, Task 3 -> James
Community 2:
Members: James
Tasks: Talk 1, Task 14, Task 15
Assigned: Task 1 -> Joe, Task 14 -> James
So essentially. Joe has to complete Task 1, and James has to complete Task 3.
I need a array (that can be encoded to json) that stores the community ID as well as all of the tasks that they have completed but, it should be easily accessible to get the community and the tasks that they have completed.
I have a list of communities that currently exist, and I would like to show all of tasks that have been completed (by the specific user) depending on the community id, as well as this, I also want to add and delete things from the "tasks" category, so need a way to easily get access to these members
I have come up with the following so far:
$progress = array (
"communities" => array(
"id" => 1,
"tasks" => array(
1 => "completed",
2 => "completed"
),
"id" => 2,
"tasks" => array(
150 => "completed",
140 => "completed"
)
),
);
But I don't know if this is the right style of array for this, since, I don't know how complex it will be when I need to add/remove or show the total amount of tasks left for a communities
UPDATE:
This array I'm working with now:
$x = array(
1 => array(
1,
2,
3,
4,
),
2 => array(
3,
5,
6,
10
)
);
Then produces this kind of JSON:
{"1":[1,2,3,4],"2":[3,5,6,10]}
Is this somewhere right? Will I be able to add and delete nodes, as well as add top layer sections to this?
Code sample as a reply to your comment
$progress = array (
"communities" => array(
1 => array(
"tasks" => array(
1 => array("status" => "completed", "assigned_users" => array("James", "Joe")),
2 => array("status" => "pending", "assigned_users" => array("James"))
),
),
2 => array(
//Content of task2
)
)
);
With an extended model like this, you'll be able to:
assign a task to one user or more
remove a user from a specific task
know which users are busy or available
count tasks and getting resources (users) assigned
Getting the task 1 of the first community
echo $progress['communities'][1]['tasks'][1];
Walk the communities collection
foreach ($progress['communities'] as $c) {
//Browse the tasks
foreach ($c['tasks'] as $t) {
var_dump($t);
}
}
I am using the VIES database to gather company data, based on European VAT number for my PHP application.
The things that I need are:
city
street name
house number
postcode
comapny name
as separate data but the VIES database is giving me all of it as a one string.
Working example:
<?php
try {
$opts = array(
'http' => array(
'user_agent' => 'PHPSoapClient'
)
);
$context = stream_context_create($opts);
$client = new SoapClient(
'http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl',
array('stream_context' => $context,
'cache_wsdl' => WSDL_CACHE_NONE)
);
$result = $client->checkVat(
array(
'countryCode' => 'PL',
'vatNumber' => '5242106963'
)
);
print_r($result);
} catch (Exception $e) {
echo $e->getMessage();
}
?>
I am receiving:
stdClass Object (
[countryCode] => PL
[vatNumber] => 5242106963
[requestDate] => 2015-02-20+01:00
[valid] => 1
[name] => COCA-COLA HBC POLSKA SPÓŁKA Z OGRANICZONĄ ODPOWIEDZIALNOŚCIĄ
[address] => ANNOPOL 20 03-236 WARSZAWA
)
But I need the address like this:
$street='ANNOPOL';
$number='20';
$city='WARSZAWA';
$postcode='03-236';
Also please keep in mind that for other companies, the street name or city can have more then one word, like "New York", so an easy solution to divide the data based on space between words doesn't work for me.
As you have stated that postal code will be in 99-999 format and assuming the street number (+ any flat identification) will always start with a number, you can use a preg_match to parse the address string:
$result = new stdClass();
$result->address = 'Wita Stwosza 15 M5 31-042 Kraków';
preg_match(
'#'
. '(.*?)' // Match as many chars as possible (street)
. '\s+(\d+(?:.*?))' // Space, then number and possibly flat (number)
. '\s+(\d\d\-\d\d\d)' // Space, then digits/dash/digits (postcode)
. '\s(.*)' // Space, then everything after that (city)
. '#',
$result->address,
$matches
);
list ($street, $number, $postcode, $city) = array_slice($matches, 1);
echo "Street: $street", PHP_EOL;
echo "Number: $number", PHP_EOL;
echo "Postcode: $postcode", PHP_EOL;
echo "City: $city", PHP_EOL;
Output:
Street: Wita Stwosza
Number: 15 M5
Postcode: 31-042
City: Kraków
As far as I can see the VIES data already has newlines built into the result. So you should be able to explode based upon the newline character. Then it will just be a case of working out if the postcode is last or the city.
To confirm what I am saying just:
echo nl2br($result->address);
Sorry for the simple question that I could research, but i crashed a database today, been here 12 hours, and want to go home.
I am rotating recursively through files trying to extract city, phone number, and email address so that I can match the city and phone to my database entries and update the users email address. In theory, they could just login with their email and request to reset their password.
heres what i need. my file contents look like this:
> Address : 123 main street City : somecity State/Province : somestate
> Zip/Postal Code : 12345 Country : United States Phone : 1231231234 Fax
> : E-Mail : example#example.com ==== CUSTOMER SHIPPING INFORMATION ===
I should note that there is other info before and after the snippet I showed. Can someone please help me with a regex to remove the 3 items? Thanks.
Try something like this, without regex..
$string = 'Address : 123 main street City : somecity State/Province : somestate Zip/Postal Code : 12345 Country : United States Phone : 1231231234 Fax : E-Mail : example#example.com ==== CUSTOMER SHIPPING INFORMATION ===';
$string = str_replace(
array(
' ==== CUSTOMER SHIPPING INFORMATION ===',
'Address',
'City',
'State/Province',
'Zip/Postal Code',
'Country',
'Phone',
'Fax',
'E-Mail'
)
, '', $string);
$string = explode(' : ', $string);
unset($string[0]);
print_r($string);
Result...
Array
(
[0] =>
[1] => 123 main street
[2] => somecity
[3] => somestate
[4] => 12345
[5] => United States
[6] => 1231231234
[7] =>
[8] => example#example.com
)
If there are linebreaks, something like this...
$string = explode("\n", $string);
foreach($string as $value){
list(, $info) = explode(' : ', $value);
echo $info . '<br />';
}
Solution with regex..
$fields = array('City', 'Phone', 'E-mail');
foreach($fields as $field){
preg_match("#$field : (.*?) #is", $string, $matches);
echo "$field : $matches[1]";
echo '<br />';
}
Result:
City : somecity
Phone : 1231231234
E-mail : example#example.com
Something like this:
Address\s*:\s*(.*?)\s*City\s*:\s*(.*?)\s*State/Province\s*:\s*(.*?)\s*Zip/Postal Code\s*:\s*(.*?)\s*Country\s*:\s*(.*?)\s*Phone\s*:\s*(.*?)\s*Fax\s*:\s*(.*?)\s*E-Mail\s*:\s*(.*?)\s
Will work if you rip out the > at the start of each line first.
proof
If you print_r that, you'll see the different components.
Note the "dot matches all" modifier. Might be even easier if you rip out newlines too (after you take out the >).
What about this
$test =
'
> Address : 123 main street City : somecity State/Province : somestate
> Zip/Postal Code : 12345 Country : United States Phone : 1231231234 Fax
> : E-Mail : example#example.com ==== CUSTOMER SHIPPING INFORMATION ===
';
preg_match('#.*City : (.+?) .*? Country : (.+?) Phone : (.+?) .*#si',$test,$res);
var_dump($res);
result
array
0 => string '
> Address : 123 main street City : somecity State/Province : somestate
> Zip/Postal Code : 12345 Country : United States Phone : 1231231234 Fax
> : E-Mail : example#example.com ==== CUSTOMER SHIPPING INFORMATION ===
' (length=217)
1 => string 'somecity' (length=8)
2 => string 'United States' (length=13)
3 => string '1231231234' (length=10)