I just threw this page together today as part of how I want my website to work. Having got it to a working state I wanted the SDMB’s resident PHP/website experts to look at it. Not because I want to show it off. Nor is my main motive to have you critique it. I just wanted to show it for the sake of showing it.
But you can critique it if you like.
I want my website to be as easy to use for the administrator (me) as possible. So my idea was that having processed a set of images on my local computer I would simply upload them to an ‘unprocessed’ secure folder on my web server in one big lump, then run a php script which would copy the files to their intended destination and add records (with basic required data) to a database.
I know my method is probably not the best so I am interested to hear ideas.
Anyway, here’s the script…
<?php
function sanitizestring($var)
{
$var = strip_tags($var);
$var = htmlentities($var);
$var = stripslashes($var);
return mysql_real_escape_string($var);
}
if (isset($_GET['section']))
{
$db_database = 'photography';
require_once('../../db.php'); //only include database stuff if the form has been submitted, to save making unnecesary connection to db
connect();
$section = sanitizestring($_GET['section']);
if ($section == "")
{
echo "Creating of sections without a name is not supported. Please enter a name for the section";
}
else
{
$result = mysql_query("select * from sections where section = '$section'") or die("Query failure on select all from sections:".mysql_error());
if(!mysql_num_rows($result))
{
mysql_query("insert into sections (section) values ('$section')") or die("Query failure on insert new section into sections:".mysql_error());
echo "section \"$section\" created";
}
else echo "section \"$section\" already exists. New images will be added to it";
$result = mysql_query("select sectionid from sections where section = '$section'") or die("Query failure on select all from sections:".mysql_error());
$row = mysql_fetch_row($result);
$sectionnumber = $row[0];
}
}
$dh = opendir('.');
echo "<p>";
$insertstring = "insert into photos (filename,sectionid) values
";
$first = "";
while(($filename = readdir($dh)) !== false)
switch(end(explode(".",$filename)))
{
case "jpg" :
case "JPG" :
case "jpeg" :
case "JPEG" :
echo "<a href=$filename target=_blank>$filename</a> ";
if (isset($sectionnumber))
{
$insertstring .= "$first('$filename',$sectionnumber)";
$first = ",
";
if(!(file_exists("../$section") && is_dir("../$section"))) mkdir("../$section");
rename($filename,"../$section/$filename");
}
}
echo "</p>";
closedir($dh);
?>
<form method="GET" action="#">
Enter a name for the section<input type="text" name="section" />
<input type="submit" value="process" name="process" />
</form>
<?
if(isset($section) && $section !="")
{
mysql_query($insertstring) or die("Query failure on inserting records into photos: ".mysql_error());
$page = $_SERVER['PHP_SELF'];
$sec = "5";
header("Refresh: $sec; url=$page");
echo "<p>Images have been moved to folder \"photography\\$section\" and records created for them in the database.<br /><br />This page will reset in 5 seconds</p>";
}
//echo "<pre>$insertstring</pre>";
?>
p.s. I realize the code doesn’t deal with duplicate records (such as if, for some reason, I run the code on the same files again) the filenames will be added to the database again, thus duplicating them. This is something I decided to live with for now.
p.p.s In case it wasn’t obvious: I’m a php beginner.
It’s acceptable code; my only nit-pick is with the formatting of the if-else statements; maybe the forum software eats up the formatting or what-not, but it can be hard to tell if statements are part of the else-block.
Other than that, beware of file permissions problems; check that your folders allows PHP to write to it with 755 permission. If you need to use 777 for PHP to write, have a chat with the webhost, or switch.
I didn’t read the whole thing because, hey, I’m lazy (let’s be honest). But I’ll suggest that your life will tend to be easier if you avoid comingling your code and your HTML so much. Putting it all mixed together like that makes things much harder to maintain in the long run.
I don’t do a whole lot of PHP, but since we’re sharing, I’ll toot my horn too. Last weekend I got mad at Wordpress (mostly because I was sick of having to constantly do security updates; also it includes about a bazillion features I don’t actually need). So I scrapped it and wrote a homebrew blogging platform. I used PHP not because I really like it, but because it’s ubiquitous – I wanted to be able to pick up my code, move it to another host and be up and running immediately. With my new setup, if my hosting company went out of business without notice, I could have things going somewhere else faster than the DNS change can propagate. Woohoo!
Beyond portability, my goals were simplicity (no features I don’t actually need right now – if it’s a “maybe some day,” it got left out) and not breaking existing links (or the RSS and Atom feeds). So I imported the important parts of the Wordpress database, and had to stick with the same basic URL design. Wordpress actually has a pretty complex URL setup, and it’s hard to duplicate completely without a lot of code, so I punted on some stuff. I don’t need or want categories, so category URLs don’t work anymore. And date indices don’t work anymore either. I looked at my logs, and no real humans were using those, so I’m not too concerned.
Anyway, here’s the result: Sean Harding/blog If you find anything broken, please let me know. I’m sure there are still a few things. I found one really stupid bug this afternoon…
ETA: One thing I know is “broken” is that it doesn’t work well in older versions of IE and probably some other browsers (I only really test it in Safari, Firefox and Chrome), and it also doesn’t work well if you don’t have a decent sized monitor and fairly fast connection (big photos). All of those limitations are things I’ve strived to avoid in every site I’ve ever built, but this time I just said “screw it.” It’s a personal site mostly aimed at my friends and family, so I focused on making it work well for them without adding a bunch of additional work for myself. Again, lazy.
Bump the page size down to 95%, and the images work fine at 1024x768, the standard browser resolution. That means the images are just 95% too big. Compared to a lot of Wordpress sites, that’s pretty darn good. Heck, I can even magnify the text and nothing breaks.
The images are 1000 pixels wide right now. I was thinking that should fit in 1024x768 (though based on my stats, almost none of my viewers have a resolution that low). I guess with the scrollbar and stuff, maybe not. I could bring them down to 950 pixels wide I guess. Not tonight, though
BTW, does The Big Picture work ok at 1024x768? Their images are 990 pixels. I figured another 10 pixels wouldn’t make much difference (and is a nice even number), but on the other hand there’s probably a good reason they chose 990…
You stripslashes then insert into your database.
If someone adds a section with a ’ in the name, your insert will fail as there will be an unmatched ’ in there (as you surround $section with '.
When your queries fail you are exposing your database table names to the end user. Not a clever thing. Someone persistent might be able to work through what fails, where and how to determine what your schema looks like. Fail with a different message without exposing your table names.
Why do you have a form with a GET? That (to me) seems weird, I would normally have a POST with a form.
Images have been moved to folder “photography\$section”
You are now also exposing your file system to the potential hacker.
require_once(’…/…/db.php’);
If you move this function up and or down the tree in your file system it won’t work. You might be better off referring to:
require_once($_SERVER[“DOCUMENT_ROOT”]."/path/to/db.php");
Then if you move your photo mover, it will still find db.php
I recommend you always match your braces.
if(!mysql_num_rows($result))
{
mysql_query("insert into sections (section) values ('$section')") or die("Query failure on insert new section into sections:".mysql_error());
echo "section \"$section\" created";
}
else echo "section \"$section\" already exists. New images will be added to it";
If you add something else to the last echo you will fail beautifully.
I recommend:
$result = mysql_query("select * from sections where section = '$section'") or die("Query failure on select all from sections:".mysql_error());
if(!mysql_num_rows($result))
{
mysql_query("insert into sections (section) values ('$section')") or die("Query failure on insert new section into sections:".mysql_error());
echo "section \"$section\" created";
} else{
echo "section \"$section\" already exists. New images will be added to it";
}
Also have a look at mysql_fetch_array vs. mysql_fetch_row
You can then refer to the column names rather than by their position.
i.e. $sectionnumber = $row[0]; would become $sectionnumber = $row[“sectionid”];
If you change what you select, you will need to change the array ids. Using an associative array makes update later easier.
Unlikely that I’ll add a section with a ’ in it, but I will look at making the code able to do that.
Good spot. The page is for private use (me) but my intention is to get better at PHP so I welcome things like this being spotted.
Ideally I should deal with errors in a more sophisticated way
Just sub-consciously taking the advice of php learning books. when get is used the resulting page can be indexed by search engines so if I’m not thinking about it I’ll absent-mindedly use GET. As this is privately used page (and there is no need for it to be indexed on search engines anyway) I’ll change it to POST
Can you or someone elaborate a bit?
Good advice. Will take
Well I am usually good at spotting this potential fail (i.e. if I did need to add something after the echo I would wrap it and the extra thing in braces. I am sometimes a stickler for reducing the number of lines required for code.
It’s some code that runs in a private section of my webpage, so if I were to link to it I’d have to provide you with the login details
When I’ve created the public part that displays the images and allows people to comment on them (the bit that is going to be pretty to look at - a challenge in itself for me) I’ll be linking to that here on the SDMB.