Need a php script diagnosis for a small snippet of code - php

Can somebody tell me what I am doing wrong really? I am going nuts, the following code works perfect on localhost/WIN and when I try it on the webhost/linux it gives warnings:
$lines = file('english.php');
foreach($lines as $line) {
$matches=array();
if (preg_match('/DEFINE\(\'(.*?)\',\s*\'(.*)\'\);/i', $line, $matches)) {
$keys[] = $matches[1];
$values[] = $matches[2];
}
}
$lang = array_combine($keys, $values);
When I test on webhost:
Warning: array_combine() expects parameter 1 to be array, null given in /home/xx/public_html/xx on line 616
But on local server (windows xp) it works perfect. I do not know what I am doing wrong, please help me resolve this nightmare :(
Thanks.

I don't see anything obviously wrong with your code, but I'm curious why you're building separate arrays and then combining them rather than just building a combined array:
// Make sure this file is local to the system the script is running on.
// If it's a "url://" path, you can run into url_fopen problems.
$lines = file('english.php');
// No need to reinitialize each time.
$matches = array();
$lang = array();
foreach($lines as $line) {
if (preg_match('/DEFINE\(\'([^\']*)\',\s*\'([^\\\\\']*(?:\\.[^\\\\\']*)*)\'\);/i', $line, $matches)) {
$lang[$matches[1]] = $matches[2];
}
}
(I've also changed your regex to handle single quotes.)

Are the php versions the same?
And are you sure you have transfered all your files to the webhost?

It seems your $keys variable is null, because you're not initializing it anywhere.
My best guess is that the english.php file on your server is empty (or does not exists), so when you try to read it nothing is saved in $keys variable;
Try adding an initial value for that variable before the foreach statement:
$lines = file('english.php');
$keys = array();
foreach($lines as $line) {
$matches=array();
if (preg_match('/DEFINE\(\'(.*?)\',\s*\'(.*)\'\);/i', $line, $matches)) {
$keys[] = $matches[1];
$values[] = $matches[2];
}
}
$lang = array_combine($keys, $values);
That way, even if the file doesn't exist or is empty you're covering all possible paths.
You should always code as if everything could go wrong, not the other way around :)

Related

what is wrong with this code, I am using PHP 8

The loop never stop, also it always print, not only when $i is equal 8
$file = file_get_contents ($fileUrl);
$i = 0;
while ($line = explode ("\r\n", $file)) {
if ($i == 8) {
print_r ($line);
exit ();
}
$i++;
}
By the way, I need to use file_get_contents because I am using DOM, but I use that code because I need the data in line number 8, is there any better way to get a specific line
It is infinite because explode always explodes the entire file string and it never fails. You can read it into an array, but this is only useful without the exit if you are doing things with other lines in the file:
foreach(file($fileUrl) as $line) {
if ($i == 8) { // actually the ninth line
print_r ($line);
}
$i++;
}
Or read it as you are and get the proper line:
$lines = explode("\r\n", $file);
print_r($lines[8]); // actually the ninth line
You're not looping through the lines. You're setting $line to an array of all the lines, not a specific line. And you're setting it to the same thing every time through the loop, so the while condition will never change.
However, the loop should stop when $i == 8 because of the exit() call. It will then print all the lines with print_r().
If you want line 8, just index the array.
$lines = explode("\r\n", $file);
if (count($lines) >= 9) {
print_r($lines[8]);
}
FYI, you can also use file() to read a file and split it into lines:
$lines = file($fileUrl, FILE_IGNORE_NEW_LINES);
if you want to get the 8th line, you can simply do this:
$line = explode ("\r\n", $file)[8];
print_r($line);
without using a loop
and regarding you question for infinite loop
$line = explode ("\r\n", $file)
returns a true, since you are just assigning an array to this variable.
you should use foreach here like this:
foreach(explode ("\r\n", $file) as $line){
// TO DO
}

multi-dimensional array possibly

I have two files that I need opened, I'm using php file to read them
$lines = file('/home/program/prog_conf.txt');
foreach ($lines as $line) {
$rows = preg_split('/\s+/', $line);
Followed by:
$lines = file('/home/domain/public_html/base/file2.cfg');
foreach ($lines as $line) {
$rows = preg_split('/=/', $line);
As I work with these two files, I need to pull info from the second one, which I seperated by =, however, I'm not sure this is the best thing to do. I wanted to add data checking from the database. The db details are in the second file like so:
dbname = databasename
dbuser = databaseuser
dbpass = databasepassword
If I echo the $rows[2], I get everything all the information I need on a single line, not on seperate lines. Meaning:
databasename databaseuser databasepassword
How do I split the information up so I can use the entries one by one?
How about:
$lines = file('/home/domain/public_html/base/file2.cfg');
$all_parts = array()
foreach ($lines as $line) {
//explode pulls apart a string based on the first value, so you could change that
//to a '=' if need be
array_merge($all_parts,explode(' ', $line));
}
This would get you all the parts of the file, one at a time, into an array. Which is what I think you wanted.
If not, just explode as needed
Maybe this aproach helps:
First as i see your second file has multiple lines, so what would do is something like this:
Assumin that every key as "db" in common we can do something like this.
$file = fopen("/home/domain/public_html/base/file2.cfg", "rb");
$contents = stream_get_contents($handle); // This function return better performance if the file isn't too large.
fclose($file);
// Assuming this is your return from the file
$contents = 'dbname = databasename dbuser = databaseuser dbpass = databasepassword';
$rows = preg_split('/db+/', $contents); // Splinting keys "db"
$result = array();
foreach($rows as $row){
$temp = preg_replace("/\s+/", '', $row); // Removing extract white spaces
$temp = preg_split("/=/", $temp); // Splinting by "="
$result[] = $temp[1]; // Getting the value only
}
var_dump ($result);
I hope this help you can try this code maybe with little modifications but works.

Subtraction between data in file1 and file2 using PHP

Suppose that I have 2 files:
File1.txt
10;30;15;40;12;14;15
23;32;10;50;12;54;60
File2.txt
2;4;5;6;7;8;9
3;6;7;8;9;0;7
I want to subtration between these 2 files. Ex 10 - 2........
PHP code:
$file1 = 'File1.txt';
$file2 = 'File2.txt';
if(file_exists($file1)){
$files = fopen($file1,'r');
while(!feof($files)){
$data = explode(";",fgets($files));
if($title ==""){
$title = $data[0];
}
if(!empty($data[3])){
$cate = $data[3];
$filepmta = fopen($file2,'r');
while(!feof($filepmta)){
$hourData = explode(";",fgets($filepmta));
if(!empty($hourData[3])){
if($title ==""){
$title = $hourData[0];
}
if(!empty($btnHour)){
echo $percentRed = ((int)$data[2] - (int)$hourData[2]);
//it loads page so long time so I don know what's error.
}
}
}
It loads the page is so long time.I don know how to fix this,Anyone know help me please,thanks.
I would recommend just simply opening both files and storing the contents of the file into memory. IE Create 2 simple loops (not nested) which iterates through both files respectively and saves the content to an array.
Then make one more loop after the first two. Iterate through the third loop based on the array size of the first two. (I'm assuming you can assume they are both the same size, but it will be a good idea to add checks to make sure loop 1 and loop 2 produce the same size/length arrays.
Within the 3rd loop iterate through both previously two generated arrays with the same index.
Pseudo Code // even tho I said I'd do pseudo code, I ended up doing it all. :-/
$file_values1 = $file_values2 = $answers = array();
while(!feof($file1)) $file_values1[] = explode(';', fgets($file)); // loop 1
while(!feof($file2)) $file_values2[] = explode(';', fgets($file)); // loop 2
foreach($file_values1 as $key1 => $sub_array) { // loop 3
foreach($sub_array as $key2 => $value) // loop 4; hehe, oh wellz
{
$answers[] = $file_values1[$key1][$key2] = $file_values2[$key1][$key2]
}
}
Basically, the nested loop 4, meh. There ARE faster answers. The 3rd loop can be improved upon, it's O(N^2). I'll leave that for you to optimize. No free lunches. :-)
fgets() doesn't move the file pointer after the last line, so you're staying on the last line, feof() still returns false and you're trapped in an infinite loop.
The common way of doing what you want is:
while (($line = fgets($handle)) !== false) {
echo $line;
}
Have a look at the code example in fgets() documentation, it's quite exhaustive.
You're making this way more complicated than it has to be.
Open your files and read them both in with file(), which will give you an array of lines in each file.
Iterate over both line arrays simultaneously with a MultipleIterator.
Convert each lines' contents to arrays with str_getcsv() and an array_map() trick.
Iterate over each line values with another MultipleIterator.
Compute the subtraction and print it.
That's all it takes! I've implemented the above algorithm below.
$file1 = 'File1.txt';
$file2 = 'File2.txt';
$file1 = file( $file1);
$file2 = file( $file2);
$iter = new MultipleIterator;
$iter->attachIterator( new ArrayIterator( $file1));
$iter->attachIterator( new ArrayIterator( $file2));
foreach( $iter as $element) {
list( $line1, $line2) = array_map( 'str_getcsv', $element, array( ';', ';'));
$val_iter = new MultipleIterator;
$val_iter->attachIterator( new ArrayIterator( $line1));
$val_iter->attachIterator( new ArrayIterator( $line2));
foreach( $val_iter as $value) {
list( $el1, $el2) = $value;
echo ($el1 - $el2); echo ";";
}
echo "\n";
}
You can see from this demo, which statically defines the files as arrays, that this produces:
8;26;10;34;5;6;6;
20;26;3;42;3;54;53;

Parsing single CSV column delimited by ~HEADER#

I have a CSV file which needs some additional processing. I've got most of our custom functionality completed. My stuck at the moment is the latest addition to the feed, multiple categories in 1 column. Here is a quick example of the new field setup.
Category01#Things~Category01#Will~Category01#Be~Category01#Here~Category02#Testing~Category02#More text here~Category02#Any data~Category02#No more data for this category~LastCategory#This~LastCategory#Is~LastCategory#The~LastCategory#End
I would need to build an array in PHP from each category available, similar to;
$category01 = array('Things', 'Will', 'Be', 'Here');
Any help would be greatly appreciated. Thanks!
If I understand your question and the format correctly, categories separated by ~, and each listed as "SomeString#Category Name", then this should to the trick. However I don't think this has anything to do with the CSV format.
$pairs = explode('~', $string);
$cats = array();
foreach ($pairs as $pair) {
list($cat_number, $cat_name) = explode('#', $pair);
$cats[] = $cat_name;
}
Gahhh. the goggles, they do nothing!
If you're unable to change that output form (and it SHOULD be changed to something nicer), you'll have to go brute force:
$csv = '...';
$categories = array();
$parts = explode('~', $csv);
foreach($parts as $part) {
$bits = explode('#', $part);
$category = (int)substr($part[0], 8);
if (!is_array($categories[$category])) {
$categories[$category] = array();
}
$categories[$category][] = $part[1];
}
Of course, this'll blow up on your LastCategory stuff at the tail end of that "csv". so... let me again STRONGLY urge you fix up whatever's generating that so-called "csv" in the first place.

Need help parsing some data in PHP

I need to be able to parse this sort of data in PHP:
Acct: 1
email : bleh#gmail.com
status : online
--------------------------------------------------
Acct: 2
email : dfgg#fgfg.com
status : banned
--------------------------------------------------
Acct: 3
signedupname : SomeUsername
somethingelse : offline
--------------------------------------------------
As you can see the data is largely random. The only thing that remains the same is the ----- seperating each entry and the Acct: 1 bits. The padding between each : often changes as does the variable to represent each bit of data.
I've tried going through and parsing it all myself using regex but I am defenately not skilled enough to be able to do it properly. At the end of this I want data according to the following:
Acct: <integer>
var1: <string>
var2: <string>
If that makes any sense at all. It doesn't need to be that effeciant, as I will need to do this about once a day and I do not mind waiting for how-ever long it needs.
Thank you. :)
Edit: This is what I did on my own:
<?php
$data = file_get_contents('records.txt');
$data = explode('******** Saved Host list with acct/variables ********', $data);
$data = explode('--------------------------------------------------', $data[1]);
foreach($data as &$dataz)
{
$dataz = trim($dataz);
}
$data = str_replace('Acct:', "\nAcct:", $data);
foreach($data as $dataz)
{
preg_match('/Acct: (.*)/', $dataz, $match);
$acct = $match[1];
preg_match('/: (.*)/', $dataz, $match);
$var1 = $match[1];
echo $var1;
}
?>
I got as far as extracting the Acct: part, but anything beyond that I simply can't get my head around.
This piece of code will take your entire input and produce an associative array for each record in your input:
// replace ----- with actual number of dashes
foreach (explode('-----', $input) as $entry) {
$entry = trim($entry);
$record = array();
foreach (explode("\n", $entry) as $line) {
$parts = explode(':', $line);
$varname = trim($parts[0]);
$value = trim($parts[1]);
$record[$varname] = $value;
}
// Do anything you want with $record here
}
Edit: I just had a look at the code you posted. You really don't need regular expressions for what you're trying to do. Regex can be really handy when used in the right place, but most of the time, it's not the right thing to use.

Categories