I have this text file that I want to read and check if the value is correct or not and then display in html file:
Audi, 2006
BMW, 2019 //date incorrect
Toyota, 2016
Frd, 2017 //name incorrect
All I did till now is:
$handle = file('src/can.txt');
$data = array();
//loop to get the value from handle
foreach ($handle as $key ) {
array_push($data, $key);
}
I wanted to continue using another loop where I create 2 array and then using explode method to separate the name of the car from the year of production.
My question is: is there any build in php method or any better way to perform the same operation?
I would suggest to use method for repeating action. Here is an example and suggest you to handle the case-senitivity of brands/makes.
I would also keep the array index for easy reference.
<?php
class File {
private $_minYear = 2000,
$_maxYear = 2018,
$_brand = array('BMW','Audi','Toyota','Ford');
private function validateYear($year) {
$year = (int)$year;
return ($this->_minYear < $year && $year < $this->_maxYear);
}
public function scan($file) {
$lines = file($file);
foreach ($lines as $key => $value) {
$data = explode(',',$value);
if (in_array($data[0], $this->_brand) && $this->validateYear($data[1])) {
$records[$key] = $value;
} else {
$errors[$key] = $value;
}
}
return array('records' => $records, 'errors' => $errors);
}
}
$file = new File;
$data = $file->scan('testcar.txt');
echo '<pre>';
print_r($data['records']);
print_r($data['errors']);
OUTPUT:
Array
(
[0] => Audi, 2006
[2] => Toyota, 2016
)
Array
(
[1] => BMW, 2019
[3] => Frd, 2017
)
Without using Class/Method
<?php
$brands = array('BMW','Audi','Toyota','Ford');
function validateYear($year) {
$year = (int)$year;
return (2000 < $year && $year < 2018);
}
function fileScan($file) {
$lines = file($file);
foreach ($lines as $key => $value) {
$data = explode(',',$value);
if (in_array($data[0], $brands) && validateYear($data[1])) {
$records[$key] = $value;
} else {
$errors[$key] = $value;
}
}
return array('records' => $records, 'errors' => $errors);
}
$data = fileScan('testcar.txt');
echo '<pre>';
print_r($data['records']);
print_r($data['errors']);
Related
Country.csv
this is countries.csv file, and i want to extract all the timezones from it, which is its 14th colomn, and the data in there is not properly json formatted. I'm trying to parse the json but it failed. Actually, I want to create an array of timezones like this
[0] => {zoneName:'Asia -> Kabul',gmtOffset:16200,gmtOffsetName:'UTC+04:30',abbreviation:'AFT',tzName:'Afghanistan Time'}
[1] => {zoneName:'Europe -> Mariehamn',gmtOffset:7200,gmtOffsetName:'UTC+02:00',abbreviation:'EET',tzName:'Eastern European Time'}
[2] => {zoneName:'Europe -> Tirane',gmtOffset:3600,gmtOffsetName:'UTC+01:00',abbreviation:'CET',tzName:'Central European Time'}
[3] => {zoneName:'Africa -> Algiers',gmtOffset:3600,gmtOffsetName:'UTC+01:00',abbreviation:'CET',tzName:'Central European Time'}
[4] => {zoneName:'Pacific -> Pago_Pago',gmtOffset:-39600,gmtOffsetName:'UTC-11:00',abbreviation:'SST',tzName:'Samoa Standard Time'}
[5] => {zoneName:'Europe -> Andorra',gmtOffset:3600,gmtOffsetName:'UTC+01:00',abbreviation:'CET',tzName:'Central European Time'}
[6] => {zoneName:'Africa -> Luanda',gmtOffset:3600,gmtOffsetName:'UTC+01:00',abbreviation:'WAT',tzName:'West Africa Time'}
what i'm doing, is this in App\Http\Controllers\TestController::class is this
public function timezone(): void {
$data = [];
if (($open = fopen(__DIR__ . '/countries.csv', 'r + b')) !== FALSE) {
while (($singleRecord = fgetcsv($open, NULL, ',')) !== FALSE) {
$data[] = $singleRecord;
}
fclose($open);
}
$data = $this->removeCharacters($data, ['[', ']']);
$data = $this->removeCharacters($data, (array)'\/', " -> ");
// $data = $this->removeCharacters($data, (array)'{}', '');
// dd(explode('},', $data[33][14]));
// dd(explode('},', $this->longJson));
// dd(explode(',', str_replace(['{', '}'], '', $data[167][14])));
$singleArray = [];
$count = count($data);
$itemsArray = [];
for ($i = 1; $i < $count; $i++) {
$singleArray[] = explode('},', $data[$i][14]);
foreach ($singleArray as $item) {
foreach ($item as $singleItem) {
$itemsArray[] = $singleItem;
}
}
}
$itemsArray = array_unique($itemsArray);
$this->printFormattedData($itemsArray);
}
private function removeCharacters($hayStack, array $charsArray, $character = ''): array {
$tempArray = [];
foreach ($hayStack as $item) {
$tempArray[] = str_replace($charsArray, $character, $item);
}
return $tempArray;
}
private function printFormattedData($data): void {
echo '<pre>';
print_r($data);
echo '</pre>';
}
Using regexp its not perfect solution, but you can transform timezone data to correct json format using function like this:
public function fixJson(string $str): string {
return preg_replace(
'/(?<=(\{|\,))(\w+)(?=\:)/',
'"$2"',
str_replace("'", '"', $zoneRaw) // may not work properly, if values may contain apostroph symbols, but seems not actual for your case
);
}
So, use this function:
$this->fixJson($data[$i][14]); // returns json string
json_decode($this->fixJson($data[$i][14])); // returns json decoded array
See usage example here https://sandbox.onlinephpfunctions.com/c/88f21
Following code would do, what you aim.
Please do not forget to mark this answer as ACCEPTED and thumbs up if it solves your problem, so that the work of the developers who help is appreciated and other developers can see in question list, that your question has already an accepted answer.
$lines = file("countries.csv");
array_shift($lines); // remove the first line with column names
$searchReplace = ['\/' => '->'];
$search = array_keys($searchReplace);
$replace = array_values($searchReplace);
$jsonFormattedTimeZones = [];
foreach($lines as $line)
{
$line = trim(str_getcsv($line)[14], " []");
$line = str_replace($search, $replace, $line);
$jsonFormattedTimeZones[] = $line;
}
print_r($jsonFormattedTimeZones);
<?php
function tambah_penumpang($daftar_penumpang, $penumpang_baru){
if(empty($namaArray)==true){
$daftar_penumpang[]=$penumpang_baru;
return $daftar_penumpang;
}else{
for($i=0; $i<count($daftar_penumpang); $i++){
if($daftar_penumpang[$i]== null){
$daftar_penumpang[$i]=$penumpang_baru;
return $daftar_penumpang;
}else{
$daftar_penumpang[] = $penumpang_baru;
return $daftar_penumpang;
}
}
}
}
$daftar_penumpang =["sandhika",null,"carl","keith"];
print_r(tambah_penumpang($daftar_penumpang,"anggoro"))."<br>"
?>
And this are the result: (i want that anggoro name in null's index)
Array (
[0] => sandhika
[1] =>
[2] => carl
[3] => keith
[4] => anggoro
)
as I'm not familiar with your naming convention , i've made a global example using array_walk as follows:
$daftar_penumpang =["sandhika",null,"carl","keith"];
array_walk($daftar_penumpang, function($v, $k, $replacement) use (&$daftar_penumpang) {
if ($v == null) {
$daftar_penumpang[$k] = $replacement;
}
}, 'anggoro');
print_r($daftar_penumpang);
live example: https://3v4l.org/vVnSq
for your case :
$daftar_penumpang =["sandhika",null,"carl","keith"];
function tambah_penumpang($daftar_penumpang, $penumpang_baru) {
array_walk($daftar_penumpang, function($v, $k, $replacement) use (&$daftar_penumpang) {
if ($v == null) {
$daftar_penumpang[$k] = $replacement;
}
}, $penumpang_baru);
return $daftar_penumpang;
}
print_r(tambah_penumpang($daftar_penumpang, 'anggoro'));
this will output:
Array ( [0] => sandhika [1] => anggoro [2] => carl [3] => keith )
Update
using for loop :
your code issue is that you will never ever get into the for loop because it is in else condition , and while the $namaArray is alway empty, so you will never go through the loop , so i've removed this check and prepared this looping to show you how to replace null values using for loop
function tambah_penumpang($daftar_penumpang, $penumpang_baru)
{
$tmpArray = [];
for ($i=0; $i < count($daftar_penumpang); $i++) {
if ($daftar_penumpang[$i]== null) {
$tmpArray[$i] = $penumpang_baru;
} else {
$tmpArray[] = $daftar_penumpang[$i];
}
}
return $tmpArray;
}
$daftar_penumpang =["sandhika",null,"carl","keith"];
print_r(tambah_penumpang($daftar_penumpang,"anggoro"));
Try with this function :
<?php
function tambah_penumpang($daftar_penumpang, $penumpang_baru){
$datas = [];
for($i = 0; $i < count($daftar_penumpang); $i++) {
$item = $daftar_penumpang[$i];
if($item === null) {
$item = $penumpang_baru;
}
$datas[$i] = $item;
}
return $datas;
}
$daftar_penumpang =["sandhika",null,"carl","keith"];
print_r(tambah_penumpang($daftar_penumpang,"anggoro"))."<br>";
I have array like this
$arr=[["a","b"],["b","c"],["d","e"],["f","c"]];
if sub arrays share same value they should be be merged to one array
expected output:
$arr=[["a","b","c","f"],["d","e"]];
I`m trying to avoid doing foreach inside foreach for solving this.
It seems your inner arrays always have 2 items. so nested loops aren't necessary. Here is a solution which I originally wrote in JS but it should work just as good and most efficient in PHP:
$arr=[["a","b"],["b","c"],["d","e"],["f","c"],["h","e"]];
$output = [];
$outputKeys = [];
$counter = 0;
foreach($arr as $V) {
if(!isset($outputKeys[$V[0]]) && !isset($outputKeys[$V[1]])) {
$output[$counter] = [$V[0], $V[1]];
$outputKeys[$V[0]] = &$output[$counter];
$outputKeys[$V[1]] = &$output[$counter];
$counter++;
}
elseif(isset($outputKeys[$V[0]]) && !isset($outputKeys[$V[1]])) {
array_push($outputKeys[$V[0]], $V[1]);
$outputKeys[$V[1]] = &$outputKeys[$V[0]];
}
elseif(!isset($outputKeys[$V[0]]) && isset($outputKeys[$V[1]])) {
array_push($outputKeys[$V[1]], $V[0]);
$outputKeys[$V[0]] = &$outputKeys[$V[1]];
}
}
var_dump($output); // [["a","b","c","f"],["d","e","h"]]
DEMO (click the execute button)
Pointers are your friends. Use them :)
The following algorithm should do what you want. It simply checks through each item and checks if it already exists in the newly created array, and if it does it adds it to that item instead of a new one:
<?php
$arr=[["a","b"],["b","c"],["d","e"],["f","c"]];
$newArr = [];
foreach ($arr as $items) {
$newKey = null;
foreach ($items as $item) {
foreach ($newArr as $newItemsKey => $newItems) {
if (in_array($item, $newItems)) {
$newKey = $newItemsKey;
break 2;
}
}
}
if ($newKey !== null) {
$newArr[$newKey] = array_merge($newArr[$newKey], $items);
} else {
$newArr[] = $items;
}
}
$newArr = array_map('array_unique', $newArr);
print_r($newArr);
Output:
Array
(
[0] => Array
(
[0] => a
[1] => b
[3] => c
[4] => f
)
[1] => Array
(
[0] => d
[1] => e
)
)
DEMO
This is solution I get for now.
$arr=[["a","b","c","f"],["d","e"]];
$sortedArray = sortFunction($arr,0,array());
function sortFunction($old,$index,$new) {
if ($index == sizeof($old)) return $new;
for ($i = 0; $i<sizeof($new); $i++) {
if (count(array_intersect($new[$i],$old[$index]))) {
$new[$i] = array_unique(array_merge($old[$index],$new[$i]), SORT_REGULAR);
return sortFunction($old,$index + 1,$new);
}
}
$new[] = $old[$index];
return sortFunction($old,$index + 1,$new);
}
I have the an array, in which I store one value from the database like this:
$stmt = $dbh->prepare("SELECT token FROM advertisement_clicks WHERE (username=:username OR ip=:ipcheck)");
$stmt->bindParam(":username",$userdata["username"]);
$stmt->bindParam(":ipcheck",$ipcheck);
$stmt->execute();
$data = array();
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
So, that gives me: array("token","token");
When I print it:
Array ( [0] => Array ( [token] => 677E2114AA26BA4351A686917652C7E1BA67A32D ) [1] => Array ( [token] => C42190F3D72C5BB6BB6B68488D1D4662A8D2A138 ) )
I then have a loop, that loops all the tokens. In that loop, I try to search for a specific token, and if it that token matches, it will be marked as "seen":
function searchForId($id, $array) {
foreach ($array as $key => $val) {
if ($val['token'] === $id) {
return $key;
}
}
}
This is my loop:
$icon = "not-seen";
foreach($d as $value){
$token = $value["token"];
$searchParam = searchForId($token, $data);
if($searchParam == $token){
$icon = "seen";
}
}
However, searchForid() simply returns 0
What am I doing wrong?
Ok, here you can see a PHP fiddle that works
$data = array();
$data[] = array('token'=>'123');
$data[] = array('token'=>'456');
function searchForId($id, $array) {
foreach ($array as $key => $val) {
if ($val['token'] === $id) {
return true;
}
}
return false;
}
$icon = "not-seen";
foreach($data as $value){
$token = $value["token"];
$searchParam = searchForId($token, $data);
if($searchParam){
$icon = "seen";
}
}
echo $icon;
It echos 'seen' which is expected since I compare the same array values, now assuming that your $d variable has different tokens, it should still work this way.
That means that your $d array does not contain what you claim it contains, could you print_r this variable and post it in your answer?
I'm trying to write a function that returns and array of the files names ordered by time modified.
Although I want to get only a specific number of files, and not the whole files in the directory.
In conclusion, I'd like to get an array that contains the newest X files from a directory.
This is my code:
public static function GetPicsDir()
{
$results = array();
$handler = opendir("pics");
while ($file = readdir($handler)) {
if ($file != "." && $file != "..") {
$results[] = $file;
}
}
closedir($handler);
return $results;
}
I don't know how to limit it and order by time modified.
I'd be glad to get any help.
Thank you
Use filemtime():
public static function GetPicsDir()
{
$results = array();
$handler = opendir("pics");
while ($file = readdir($handler)) {
if ($file != "." && $file != "..") {
$results[$time] = filemtime($file);
}
}
arsort($results);
closedir($handler);
return $results;
}
You can use glob
$date = strtotime('2013-01-10 10:00:00');//The date from you want to get the files
$matches = glob('dir/*.*');
$result=array();
if (is_array($matches)) {
$a=0;
foreach ($matches as $filename) {
if (filemtime($filename) >= $date) {//only output file >= your $date
$result[$a]['FileName'] = $filename;
$result[$a]['DateCreated'] = gmdate("Y-m-d H:i:s", filemtime($filename));
}
$a++;
}
}
if(count($result)>=2){//order array if it has at least 1 match
foreach ($result as $key => $row) {
$new_array[$key] = $row['DateCreated'];
}
array_multisort($new_array,SORT_DESC,$result);//Show most recent first
}
using array_multisort to sort by dates SORT_DESC
echo '<pre>';
print_r($result);
echo '<pre>';
Output:
Array
(
[0] => Array
(
[FileName] => test.php
[DateCreated] => 2013-10-20 05:43:06
)
[1] => Array
(
[FileName] => test.sql
[DateCreated] => 2013-09-20 23:38:05
)
[2] => Array
(
[FileName] => general.php
[DateCreated] => 2013-09-02 00:58:33
)
)
If you only want to sort the files by last modified date, you can use
ftp_nlist($conn, '-t .');
This will not tell you what the date for each file is, though.
If you want to get the modified date as well, you can use ftp_rawlist and parse the output. Here's a quick example I scraped together:
$list = ftp_rawlist($ftp, '.');
$results = array();
foreach ($list as $line) {
list($perms, $links, $user, $group, $size, $d1, $d2, $d3, $name) =
preg_split('/\s+/', $line, 9);
$stamp = strtotime(implode(' ', array($d1, $d2, $d3)));
$results[] = array('name' => $name, 'timestamp' => $stamp);
}
usort($results, function($a, $b) { return $a['timestamp'] - $b['timestamp']; });
At this point $results contains a list sorted in ascending last modified time; reverse the sort function to get the list in most recently modified first format.