Re: using csv files (import? convert to xml? any ideas?)

2007-01-04 Thread nate


http://us2.php.net/fgetcsv


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups Cake 
PHP group.
To post to this group, send email to cake-php@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/cake-php?hl=en
-~--~~~~--~~--~--~---



Re: using csv files (import? convert to xml? any ideas?)

2007-01-04 Thread Chris Hartjes


On 1/4/07, TWIOF [EMAIL PROTECTED] wrote:


Is there a way to search csv files with php? Could i convert it to xml
and do it that way?

Any ideas would be much appreciated.

Thanks



If you know the names of all the columns, then I think you could do
the following:

1) read in the file one line at a time
2) then implode the csv string into an array
3) then pull out the info you need need because you already know how
to map each element in the array to a relevant element.

I think XML is overkill for this, but that's just my opinion.  Also,
if the info is changing all the time then using a DB is also
unnecessary.

On a related note, I created a parser for the Sportsticker XML feed
because we needed to create dynamic scoreboards and post stories
pulled from the feed to our various forum sites.  For the scoreboard,
I simply created XML files for the latest scores and wrote those to a
location that the forum sites could read.  Nice and simple, no
database required because there was no need for retrieval at a later
date of older scores.

Hope that helps.

--
Chris Hartjes

My motto for 2007:  Just build it, damnit!

rallyhat.com - digitial photo scavenger hunt
@TheBallpark - http://www.littlehart.net/attheballpark
@TheKeyboard - http://www.littlehart.net/atthekeyboard

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups Cake 
PHP group.
To post to this group, send email to cake-php@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/cake-php?hl=en
-~--~~~~--~~--~--~---



Re: using csv files (import? convert to xml? any ideas?)

2007-01-04 Thread [EMAIL PROTECTED]


If it helps, I wrote a component for handing CSV files and put it on
the Bakery, but it hasn't been published. The text is below:

CSV (comma-separated values) is a simple format for storing data. As
such, adding support for it in CakePHP is simple as well. Here we go...

[h4]Exporting CSV[/h4]
Exporting data is as simple as querying the model and adding a
delimeter character. For the interest of generalizing the solution, I
made the delimiter default to a comma but allow for anything. Also, I'm
using this mostly in situations where I don't want to see every value,
so I allowed for the possibility of narrowing the results with the
'where' clause.
[code]
function exportCSV($where = NULL, $delimeter = ',') {
   $csv = '';

   $this-recursive = -1;
   $rows = $this-findAll($where);

   foreach($rows as $row) {
   $row[$this-name] = str_replace('\\', '',
$row[$this-name]);
   $row[$this-name] = str_replace($delimeter, '\\' . $delimeter,
$row[$this-name]);
   $csv .= implode($delimeter, $row[$this-name]) . chr(13);
   }

   $csv = trim($csv);
   return $csv;
}
[/code]
As you can see, we are escaping the delimiter character. Also, it is
important to escape the escape character (in this case a backslash).

[h4]Importing CSV[/h4]
Importing CSV is a little trickier than exporting it because we want to
make sure we get a nicely formatted multi-dimensional array that
CakePHP's save function can chew on. Again, we will ask for the
delimiter of choice but default to a comma. When importing the CSV that
we previously exported, we want to do things in roughly the reverse
order. First, we are going to split the string at the line breaks into
rows. Second, remove escaped characters and replace a non-separating
comma (or other delimiting character) with a placeholder. Third, split
the rows where the delimiting character occurs. Fourth, replace the
placeholder with the character we took out. (I'll explain that in a
second.) Then finally, put humpty-dumpty back together again in the
expected structure with the correct keys.
[code]
function importCSV($csv, $delimeter = ',') {
   $keys = $this-getFieldNames();
   $rows = array();

   $csv = trim($csv);
   $csv_rows = explode(chr(13), $csv);

   foreach($csv_rows as $csv_row) {
   $csv_row = str_replace('', '\\', $csv_row);
   $csv_row = str_replace('\\' . $delimeter, chr(26), $csv_row);
   $row = explode($delimeter, $csv_row);
   $row = str_replace(chr(26), $delimeter, $row);

   $row = array_combine($keys, $row);
   $rows = array_merge_recursive($rows, array(array($this-name =
$row)));
   }

   return $rows;
}
[/code]

[h4]What's with the placeholder?[/h4]
Imagine we had a record, like the following:
[code]
[id] = 1
[product] = Black\Blue Shirt
[comment] = Nice, but wrinkles easy.
[/code]
Assuming that we use a comma as a delimiter when we exported to CSV we
would get the following line:
[code]
1,Black\\Blue Shirt,Nice\, but wrinkles easy.
[/code]
Now we want to import this. First, strip the escaped escape character
to get this:
[code]
1,Black\Blue Shirt,Nice\, but wrinkles easy.
[/code]
This looks great, but we have a problem. If we stripped the escape
character before the comma in the third value, we would end up with a
delimiting character that would result in four fields. Furthermore, if
we tried to explode the string by the delimiting character
[b]before[/b] stripping it we would still have four fields.

I solved this problem by turning those characters into a placeholder
character, then splitting the string by the delimiter, and adding the
original character back in. (I'm using a carat '^' in place of the
invisible character that I actually use.)
[code]
1,Black\Blue Shirt,Nice^ but wrinkles easy.
[/code]
After exploding we get:
[code]
[id] = 1
[product] = Black\Blue Shirt
[comment] = Nice^ but wrinkles easy.
[/code]
Then, stick the original character back:
[code]
[id] = 1
[product] = Black\Blue Shirt
[comment] = Nice, but wrinkles easy.
[/code]

[h4]Finding Field Names[/h4]
In order to make our structured array that's compatible with CakePHP's
save function, we need to know the field names of our model table.
Although I'm sure Cake does this at some point in the code, I felt like
having my own simplified function for our purposes. I'm basically using
MySQL's DESCRIBE function to return the field names and then I'm
returning them in a form of an array (perfect for use with combining
with the above functions).
[code]
function getFieldNames() {
   $names = array();
   $table_name = $this-tablePrefix . $this-table;
   $descriptions = $this-query('desc ' . $table_name);
   foreach($descriptions as $description) {
   array_push($names, $description[0]['Field']);
   }
   return $names;
}
[/code]

[h4]In Use[/h4]
Now that all of our models have the ability to import and export CSV,
putting it to use is simple. We could do something like the following
to do an export:
[code]
$csv = $this-Product-exportCSV();
[/code]
To import our