Jump to content
rikbignell

fgetcsv with regex replacement for an url

Recommended Posts

Hi,

I have cobbled together some code to display output from a speedtest csv as a php page.  The output shows the data exactly how i want but leaves the url as text.  I would like the url replaced with href to make it a link.

I have included my attempts but this is not working.  I feel like im close but ${1} is not putting the link into the href.

 

Before:

http://www.richardbignell.co.uk/speedtest.php

After:

http://www.richardbignell.co.uk/speedtest1.php

As you can see it shows the link as i want but the link contains nothing. What am i doing wrong?  I'm not looking for a better way of doing this, i'd like to just fix the preg_replace command please.

 

<?php
// Create a table from a csv file 
echo "<html><body><table>\n\n";
$f = fopen("speedtest.csv", "r");
while (($line = fgetcsv($f)) !== false) {
        $row = $line[0];    // We need to get the actual row (it is the first element in a 1-element array)
        $cells = explode(";",$row);
        echo "<tr>";
        foreach ($cells as $cell) {
            echo "<td>" . preg_replace("/http.*png/","<a href=${1}>Link</a>",$cell) . "</td>";
            #echo "<td>" . str_replace("http",'<a href="http://www.richardbignell.co.uk">Link</a>',$cell) . "</td>";
            #echo "<td>" . htmlspecialchars($cell) . "</td>";
        }
        echo "</tr>\n";
}
fclose($f);
echo "\n</table></body></html>";
?>

 

Share this post


Link to post
Share on other sites

You're making it more complicated than it has to be.

The CSV format probably won't change anytime soon, right? Which means you can fairly reliably say that it's the share_url column that has the link. And the entire value of that column is the link.

 

But before that, the whole "we need to get the actual row" thing bothers me quite a bit. You know you can customize how fgetcsv() works? It's in the documentation.

while (($line = fgetcsv($f, 1024, ";")) !== false) {

Let's also clean up the code to be a bit smarter. Like, you can get the header line on its own and then build an array you can work with more easily.

$header = fgetcsv($f, 1024, ";");
while (($line = fgetcsv($f, 1024, ";")) !== false) {
	$cells = array_combine($header, $line); // cells[start], cells[stop], etc.
	echo "<tr>";
	foreach ($cells as $cell) {
		echo "<td>" . $cell . "</td>";
	}
	echo "</tr>\n";
}

I'm not using htmlspecialchars because I trust the data to be safe.

Now back to the original problem. You want the share_url to be a link. So make it a link. (If you don't trust the data to be safe then this you'll want htmlspecialchars() back but then this won't quite work...)

$cells["share_url"] = "<a href='" . $cells["share_url"] . "'>Link</a>";

If you run that you'll see there's no header in the output anymore. That's because it was read before the while loop. I assume you do want that header. But making the main loop output it too means there will be a link around it. So what I would do is just copy/paste the output code and use it for the header; normally duplicating code like that is a bad sign, but here it's easier to do that then to have to tweak the loop to handle just that one row.

$header = fgetcsv($f, 1024, ";");
echo "<tr>";
foreach ($header as $cell) {
	echo "<td>" . $cell . "</td>";
}
echo "</tr>";

All together, plus another edit or two,

<?php

echo "<html><body><table>\n\n";
$f = fopen("speedtest.csv", "rt"); // 't' means text mode - see fopen()

$header = fgetcsv($f, 1024, ";");
echo "<thead><tr>"; // using a thead for nicer markup
foreach ($header as $cell) {
	echo "<th>" . $cell . "</th>"; // th for header cells, are typically bolded
}
echo "</tr></thead><tbody>"; // ...and a tbody

while (($line = fgetcsv($f, 1024, ";")) !== false) {
	$cells = array_combine($header, $line); // cells[start], cells[stop], etc.
	$cells["share_url"] = "<a href='" . $cells["share_url"] . "'>Link</a>";

	echo "<tr>";
	foreach ($cells as $cell) {
		echo "<td>" . $cell . "</td>";
	}
	echo "</tr>\n";
}

fclose($f);
echo "\n</tbody></table></body></html>";

?>

 

Share this post


Link to post
Share on other sites

Thank you so much for taking the time to help me on this.  I love forums like this where coders are just there to help each other.

I wish my email notifications were working though as i only just saw this.  I spent another 2 hours trying to get it to work and managed to fudge it.  I like your way much better though so i'll use your code.

Here's my sloppy attempt. Feels good that i worked through it and learned a few things about php.

 

<?php
// Create a table from a csv file 
echo "<html><body><table>\n\n";
$f = fopen("speedtest.csv", "r");
while (($line = fgetcsv($f)) !== false) {
        $row = $line[0];    // We need to get the actual row (it is the first element in a 1-element array)
        $cells = explode(";",$row);
        $pattern = '/(^http.*png$)/';
        $replacement = '<a href=$1>Link</a>';
        echo "<tr>";
        foreach ($cells as $cell) {
            echo "<td>" . preg_replace($pattern,$replacement,$cell) . "</td>";
        }
        echo "</tr>\n";
}
fclose($f);
echo "\n</table></body></html>";
?>

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.