As you know on the front page there is my image rotation. It's a very basic script written by a friend of mine. Now since my PHP isn't that crash hot, I was wondering if some of the techie people here could help me. In return I'll give you well, nothing, since I have no money and no one has donated anything :P But I'll credit your fine work none the less.
Now below is the code. The problem is that I need it to avoid trying to load HTML files, and only images. Currently it will just load any file, read its extension, and send the appropriate MIME headers.
<?php
/*
Copyright (C) 2004 Adam Smith
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or(at your option) any later version.
*/
$directory = "images/front/src";
$fd = opendir($directory);
$files = array();
$i = 0;
while (false !== ($file = readdir($fd))) {
if ($file != "." && $file != "..") {
$files[$i] = $file;
$i++;
}
}
$i = 0;
closedir($fd);
$file = array_rand($files);
preg_match("/\..*$/", $files[$file], $type);
if ($type = '.jpg' || $type = '.jpeg') {
$contenttype = 'image/jpeg';
} else if ($type = '.gif') {
$contenttype = 'image/gif';
}
header("Content-Type: $contenttype");
readfile($directory.'/'.$files[$file]);
?>
I'm not that hot at php myself, but you sould be able to do something like this for the last part of the code:
preg_match("/\..*$/", $files[$file], $type);
if ($type = '.jpg' || $type = '.jpeg') {
$contenttype = 'image/jpeg';
} else if ($type = '.gif') {
$contenttype = 'image/gif';
} else if ($type = '.html' || $type = '.htm") {
$skip = 1;
}
if ($skip!=1) {
header("Content-Type: $contenttype");
readfile($directory.'/'.$files[$file]);
}
#!/usr/bin/perl
my $directory="images/front/src";
my @files=(glob("$directory/*.jpg"),glob("$directory/*.png"),glob("$directory/*.gif"));
my $file=$files[rand @files];
print "Status: 302 Found\n";
print "Location: $file\n";
print "\n";
Or, if you only have image files in that directory, you can change line 4 to:
my @files=glob("$directory/*");
> A PHP Problem. Help me fix it!
> #!/usr/bin/perl
snicker
Also: remember that iichan's banners eventually had a problem with the board auto-deleting things as they got older. Is that going to happen here?
>>8
Wasn't that because the images where actually in threads on a board?
Oh, and i made a mistake in my posted code in case youre going to use it:
} else if ($type = '.html' || $type = '.htm") {
should be (" to ')
} else if ($type = '.html' || $type = '.htm') {
>>8
Not unless they come existance by the way of a managed post.
If you just plop the files on the server and use a pattern in the name, they'll stick around.
To be extra sure, don't keep 'em in src/. Make a banners/ directory and put 'em in there. You can even make the directory read-only so you can't accidentally delete them.
This code is really really strange. It works too hard at just about everything... The below is untested, but you should get the idea that it does what you want it to do with much less hemming and hawing. It will also ignore directories and fail gracefully if it can't find a file to use; your above code will not.
<?php
$dir="images/front/src";
$url="http://www.website.xyz/images/front/src/"; //http path to the images dir
$good=array("gif","jpg","jpeg","png"); //lowercase only
$files=array();
$fd=opendir($dir);
while (($file=readdir($fd)!==false) {
if (is_file($file) && in_array(strtolower(substr(strrchr($file, "."), 1)),$good)) {
$files[]=$file;
}
}
closedir($fd);
if (count($files)>0) {
$it=array_rand($files);
header("Location: ".$url.$file);
}
?>
Er... By "this code" above, I meant the code in >>2. My code, of course, is flawless.
('cept I don't know what it will do if it encounters a file without an extension...)
>>8
Shouldn't do. This is more of a reason for you to submit something ^_^
Oh, and after this I may move the imageboard that powers it off wakabazero and just use plain wakaba. Thanks for your code peoples.
Needs more getimagesize() and less munging around with strings and regular expressions trying to infer file type.
>My code, of course, is flawless.
$it=array_rand($files);
header("Location: ".$url.$file);
Eh? $file is the last file you read in the readdir() loop, no?
Pfft, you're right. I actually made that correction in my text editor; I must have forgotten to re-copy and paste it. (No, really, I did...)
Anyway, so that line should read
header("Location: ".$url.$it);
Or you can remove both those two lines >>14 mentions and replace it with one:
header("Location: ".$url.array_rand($files));
hmm, doesn't array_rand() return the key? So:
header("Location: " . $url . $files[$it]);
I've never actually used it, so maybe there's a nuance that the reference document doesn't indicate.
>>7
Honestly, since most the site uses perl anyway, why bother keeping a PHP banner rotator?
Ask Lain about his abject hatred of PHP as a direct result of the insanity needed to properly secure it...
I can't help but notice that my Perl script is six simple, straightforward statements, while the PHP one is a mangled mess of nested parentheses and mysterious loops.
Oh, come on, you want to talk about Perl and "mysterious" code? You won't win that one. :P glob
...
"glob" is a mysterious UNIX word! Not a mysterious Perl word! Perl is just borrowing it.
<?php
$dir = "/some/dir";
$url = "http://some/url";
$x=explode("\n",cd $dir; ls *.jpg *.png *.gif);
header("Status: 302 Found\n");
header("Location: $url/" . $x[array_rand($x)]);
?>
Not how I would normally do it, but hey, no loops.
>>23: Brilliance... except...
$x=explode("\n",shell_exec("cd ".$dir.";ls -1 *.jpg *.jpeg *.png *.gif"));
ought to work better. ls -1
forces single-column output.
Also, this will break on Windows, but... who cares? Good thinking, my man.
Also, is sending a "Status" header really necessary?
>>24
Status headers tell the browser that the file is there. You kind of need them.
<?php
$dir = "/some/dir";
$url = "http://some/url";
$x=array_join(glob("*.jpg"),glob("*.png"),glob(*.gif"));
header("Location: $url/" . $x[array_rand($x)]);
?>
...if you must use such a language. array_join()
? array_rand()
? What the hell is THAT supposed to be?
>ls -1 forces single-column output.
ls only shows multi-column output when output is to a terminal, otherwise it is 1-column, so it doesn't hurt but it's not necessary here.
shell_exec() is generally a good idea but since I'm explicitly setting $dir and there are no other variables in the call, I skipped it.
>$x=array_join(glob(".jpg"),glob(".png"),glob(*.gif"));
I presume you mean array_merge() as I don't see a ref for an array_join(). I never knew there was a glob() in PHP, but it looks like you can do this:
<?php
$dir="/some/path";
$url="http://some/url";
chdir($dir) or die ("Directory not found");
$a = glob("*.{jpg,png,gif}",GLOB_BRACE);
header("Status: 302 Found");
header("Location: $url/" . $a[rand(0,(count($a)-1))]);
?>
Look! No array_xxx() calls!
BTW, the cd/chdir is required otherwise you get full path names in $a that you have to munge if you want to feed it to header().
>shell_exec() is generally a good idea but since I'm explicitly setting $dir and there are no other variables in the call, I skipped it.
I don't understand. Can you actually put UNIX command line code in the middle of a PHP script like that and have it execute? The line in question is this:
$x=explode("\n",cd $dir; ls *.jpg *.png *.gif);
Also, everyone, please be sure to allow for .jpeg for us dorks who refuse to use DOS filenames when it's not necessary. :) (and .tiff, .mpeg, etc)
h-cube, I ask again: Is the 302 header necessary? Especially when you're redirecting the browser? Seems wrong in that case; "The file's here -- no, wait, it's over here!" (And wouldn't that header be sent automatically anyway?)
> Can you actually put UNIX command line code in the middle of a PHP script like that and have it execute? The line in question is this:
> $x=explode("\n",cd $dir; ls *.jpg *.png *.gif);
Actually, my example had backticks around the Unix commands but I guess that's one of the magic characters here and got stripped.
And I was wrong about shell_exec() - I confused it for escapeshellcmd(), which provides some protection against malicious user input. shell_exec() is functionally equivalent to using backticks so is probably preferable.
Re: 302 - I was mistaken to include it. I was trying to match waha's perl example and I actually never used it before. PHP automatically prepends an Status: 302 if you call a header("Location:"), so while it doesn't really hurt to do so explicitly, it's not necessary.
If you want to call a "Location:" header with another status code (say, a 301 which indicates permanent relocation), then you should call that header separately.
Would a programming board in the future be nice?
>>32
Eh, there's a few of those around already. No need to open yet another one.
Bit late for that. It's at http://4-ch.net/code/