|
Anybody got any tricks for dealing with php uploads? I'm in the middle of rewriting a site/cms, and I'd really prefer not to have to deal with 777 directory permissions. This particular upload form isn't public and has some upload validation going on, but the more layers of security I can wrap it in, the better. I actually came up with a half-cocked idea for this issue last night (saving uploads to a temp dir outside the web root, then having a crontabbed script run every 5 or 10 minutes to move files to their intended directories [paths embedded in the filename] which should sidestep the directory owner/writing permission problems that will crop up when using a php script via http), but if anybody has any other ideas I'm all ears.
|
# ? Jun 3, 2011 20:23 |
|
|
# ? May 16, 2024 12:46 |
|
Doesn't the directory you're moving uploads into only have to be owned/writable by the user your webserver runs under? It shouldn't have to be 777, and again, even if it is 777, that doesn't mean people can just visit your website and put files in there. Your bigger security issues regarding file uploads are making sure they're the right size, the right type, and not blindly outputting them to the client without verifying they are "correct".
|
# ? Jun 3, 2011 20:32 |
|
It shouldn't be 777, run suexec or something. .htaccess -> disable php, only allow GET, only allow certain extensions
|
# ? Jun 3, 2011 22:19 |
|
php:<? $time = strtotime($q); $myDate = date('N',$time); if ($myDate = '1') //Monday { $array = array(""); } if ($myDate = '2') //Tuesday { $array = array(""); } if ($myDate = '3') //Wednesday { $array = array("06:00AM","07:00AM","07:30AM","08:00AM","08:30AM","09:30AM","10:00AM","10:30AM","11:00AM","11:30AM","12:00PM","12:30PM","02:00PM","02:30PM","04:00PM","04:30PM","05:00PM"); } if ($myDate = '4') //Thursday { $array = array(""); } if ($myDate = '5') //Friday { $array = array("08:00AM","08:30AM","09:30AM","10:00AM","11:00AM","12:30PM","02:30PM","03:00PM"); } ?> Anybody see something obvious I'm missing?
|
# ? Jun 4, 2011 02:49 |
|
if ($myDate = '1') should be if ($myDate == '1') You are assigning with =, when what you mean to do is to check using ==.
|
# ? Jun 4, 2011 03:12 |
|
LLJKSiLk posted:
You aren't doing this: php:<? $time = strtotime($q); $myDate = date('N',$time); switch ($myDate) { case: '3': //Wednesday $array = array("06:00AM","07:00AM","07:30AM","08:00AM","08:30AM","09:30AM","10:00AM","10:30AM", "11:00AM","11:30AM","12:00PM","12:30PM","02:00PM","02:30PM","04:00PM", "04:30PM","05:00PM"); break; case '5': // Friday $array = array("08:00AM","08:30AM","09:30AM","10:00AM","11:00AM","12:30PM","02:30PM","03:00PM"); break; default: $array = array(""); } ?> Lumpy fucked around with this message at 03:32 on Jun 4, 2011 |
# ? Jun 4, 2011 03:30 |
|
Thank you both. That should teach me a lesson to quit coding on the fly in Notepad.
|
# ? Jun 4, 2011 04:10 |
|
I'm trying to create a download script, but I don't seem to be getting anywhere. The script below is located in /var/www/html/files/secure/. php:<?php define('SERVER_DOC_ROOT', $GLOBALS['_SERVER']['DOCUMENT_ROOT']); require_once(SERVER_DOC_ROOT . '/wp-blog-header.php'); // gives access to WordPress constants and functions $file = $_GET['download']; if ( is_user_logged_in() && file_exists(ABSPATH . "../resources/" . $file) ) { header("Content-Description: File Transfer"); header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=" . basename(ABSPATH . "../resources/" . $file)); header("Content-Transfer-Encoding: binary"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: private", FALSE); header("Content-Length: " . filesize(ABSPATH . "../resources/" . $file)); ob_clean(); flush(); readfile(ABSPATH . "../resources/" . $file); exit(); } ?> When I try to download the existing target file using the appropriate URL, I receive a generic file not found error. What am I doing wrong?
|
# ? Jun 7, 2011 06:17 |
|
Wait, doesn't "$file = $_GET['download'];" directly let people just do ../../../../../../../../etc/passwd?
|
# ? Jun 7, 2011 06:25 |
|
Probably, but I'm just trying to get the script to do what I want to do currently.
|
# ? Jun 7, 2011 07:29 |
|
Do you get a 404 File not Found, or a system exception that the file you're trying to read doesn't exist? In case of the last situation: have you tried printing the location of the file it's trying to access? To be honest, that must've been your first step in that case. Obviously we don't know how much you already debugged and the results of that debugging, so did you do any debugging? What happened?
|
# ? Jun 7, 2011 08:56 |
|
geonetix posted:Do you get a 404 File not Found, or a system exception that the file you're trying to read doesn't exist? This is what prints: code:
|
# ? Jun 7, 2011 09:09 |
|
Black Eagle posted:Just a 404. So this is the correct path to your file? code:
|
# ? Jun 7, 2011 11:38 |
|
Do you actually request the file? Or is there another reason a 404 might be yielded? edit: don't think I can really help without actually trying. What I would do is: reverse the condition so that you yield a 404 page if the file does not exist and exit there and then. yet, if all is fine, just do the readfile() at the end and no exit() call, that might cause other prepend and append scripts to continue working properly. Its' been a while since I've done some PHP, so I might be mistaken. geonetix fucked around with this message at 15:44 on Jun 7, 2011 |
# ? Jun 7, 2011 11:53 |
|
Lumpy posted:So this is the correct path to your file? geonetix posted:Do you actually request the file? Or is there another reason a 404 might be yielded? Yes, I think so. But here's something interesting. php:<?php define('SERVER_DOC_ROOT', $GLOBALS['_SERVER']['DOCUMENT_ROOT']); require_once(SERVER_DOC_ROOT . '/wp-blog-header.php'); $path = "/var/www/resources/"; $file = basename($_GET['download']); if ( file_exists($path.$file) ) { header("Content-Description: File Transfer"); header("Content-Disposition: attachment; filename=$path.$file"); header("Content-Type: application/pdf"); header("Content-Transfer-Encoding: binary"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: private", FALSE); header("Content-Length: " . filesize($path.$file)); header("Expires: 0"); ob_clean(); flush(); readfile($path.$file); exit(); } else { die('Error: File not found - '.$path.$file); } ?>
|
# ? Jun 7, 2011 13:13 |
|
Black Eagle posted:If I set $path to an incorrect value, the script will die per the else condition. However, if $path is correct, the script will produce a 404. Does Apache have read access to that file?
|
# ? Jun 7, 2011 16:44 |
|
Stupid question: what is the proper way to iterate a list of mysql rows into a template? I have done it plenty of times before but my memory is failing me. I want something like this: foreach($item as $num) { echo '<div class="stuff">' . $item['name'] . '</div>'; } and for every row in the db, have it create a new stuff div with the info from that row. What's the proper way to do this? I'm currently using mysql_fetch_array on a query like: SELECT * FROM ' . DBNAME . '.items'; and it's only returning the first row in the quantity of the array keys. The array itself only contains the first row though so maybe I've got my SQL wrong?
|
# ? Jun 7, 2011 20:09 |
|
revmoo posted:Stupid question: what is the proper way to iterate a list of mysql rows into a template? I have done it plenty of times before but my memory is failing me. I want something like this: mysql_fetch_array() only fetches one row. You need to loop over it, while ($row = mysql_fetch_array($result)). Each time it's called it advances the result resource's internal pointer, so when there's no more rows, it'll exit the while loop.
|
# ? Jun 7, 2011 20:25 |
|
Golbez posted:mysql_fetch_array() only fetches one row. You need to loop over it, while ($row = mysql_fetch_array($result)). Each time it's called it advances the result resource's internal pointer, so when there's no more rows, it'll exit the while loop. Perfect. Just the info I needed. Thanks a ton!!
|
# ? Jun 7, 2011 20:30 |
|
Begby posted:Does Apache have read access to that file? EDIT: Yes, Apache can read the file. I commented out the headers and readfile() returned gobbledygook, so it looks like I might have a header problem. EDIT 2: These headers are causing the file to not be found. php:<? header('Content-Disposition: attachment; filename="'.$path.$file.'"'); header('Content-Type: ' . $mime); ?> EDIT 3: So, the problem is solved, I suppose, from the PHP end. The WordPress headers were preventing a forced download. Of course, now I have to figure out how to integrate the two. EDIT 4: FYI: WordPress needs this: php:<? header('Content-Type: ' . $mime, TRUE, 200); ?> Adraeus fucked around with this message at 00:23 on Jun 8, 2011 |
# ? Jun 7, 2011 23:26 |
|
Anyone have any ideas for making this array search function more strict?php:<? function find($string, $array = array()) { foreach($array as $key => $value) { unset($array[$key]); if(stripos($value, $string) !== false) $array[$key] = $value; } return $array; } ?> quote:Book of Endriags
|
# ? Jun 9, 2011 11:44 |
|
Black Eagle posted:Anyone have any ideas for making this array search function more strict? According to http://php.net/manual/en/control-structures.foreach.php quote:Note: I think this is the root of your problem. Personally I would prefer to build a new array, rather than mess around with the old one and then return it. Also, (strongly held personal opinion incoming) never use a control structure like "if" without using a pair of braces around the statement(s) it affects. code:
|
# ? Jun 9, 2011 12:11 |
|
Hammerite posted:I think this is the root of your problem. quote:Array ( [81] => book of endriags [57] => endriag armor enhancement [319] => endriag gland extract [250] => endriag mandible [651] => endriag queen pheromones [199] => endriag contract [249] => endriag embryo [251] => endriag saliva [252] => endriag skin [253] => endriag teeth [254] => endriag venom [992] => endriags trophy [776] => schematic endriag armor enhancement ) Here's the search results function: php:<? function get_keyword_results() { if(isset($_POST['item_name'])) { $query = lowercase($_POST['item_name']); } else { $query = 'endriag'; // default: exit(); } global $items; $names = array(); foreach($items as $item) { array_push($names, $item["item_name"]); } $names = array_unique($names); $results = array(); foreach($names as $name) { array_push($results, $name); asort($results); } $results = array_map('lowercase', $results); $results = find($query, $results); echo "<p>"; print_r($results); echo "</p>"; $results = array_keys($results); foreach($results as $result) { echo '<tr>'; echo ' <td>' . $items[$result]['item_name'] . '</td>'; echo ' <td>' . $items[$result]['item_source'] . '</td>'; echo ' <td>' . $items[$result]['game_version'] . '</td>'; echo '</tr>'; } } ?>
|
# ? Jun 9, 2011 13:22 |
|
Black Eagle posted:
Are you getting every single item from your database, storing it in a variable and then using PHP to search through it? This doesn't seem like a good solution. You'd be better off with a simple SELECT name FROM items WHERE name LIKE :search
|
# ? Jun 9, 2011 14:36 |
|
Let's say I have a datetime, June 16 2011 at 7:00. I want to be able to check at, say, August 5 2011 at 7:00 and be able to tell that it is exactly a multiple of 1 day since the first date, whereas 7:01 would not count, since it is not an exact multiple. Another test set: Let's say we have June 16 2011 at 7:00, and I want to check if a particular minute is within an interval of exactly 2 hours since then. So 9:00, 11:00, 13:00, etc. would count, but 9:30 and 10:00 would not. And this could continue for days and months - September 1 at 7:00 would still count as within every 2 hours. (And no, at the moment I don't know how I'm going to handle DST ) Does anyone know if there's a simple way in either PHP or MySQL to handle this?
|
# ? Jun 9, 2011 21:53 |
|
MySQL date functions: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html Specifically time() for the first one and date_add() for the second.
|
# ? Jun 9, 2011 22:02 |
|
Doctor rear end in a top hat posted:MySQL date functions: The solution to the first is so easy I'm embarassed to not have seen it. But, that only works for easy things. What if the interval were every 2 days, instead of every 1? Or 5? And in the case of the second, would I simply have to loop date_add()? I mean, let's say the start time is 6/16 at 7am. On December 25, I still want to find out if 9am is in a 2 hour interval since then. (And the best part: it wouldn't, thanks to daylight saving time. ) Edit: Someone on SO pointed out that I could use DateInterval. Sadly, that's 5.3 and I'm langushing in 5.1. Golbez fucked around with this message at 22:15 on Jun 9, 2011 |
# ? Jun 9, 2011 22:10 |
|
I think there's a way to do a modulus, so you could try date_diff(date1,date2) MOD 5 as blarg HAVING blarg = 0
|
# ? Jun 9, 2011 22:15 |
|
Doctor rear end in a top hat posted:I think there's a way to do a modulus, so you could try So, brainstorming in freehand here for a moment... Start date is 2011-06-15 07:00:00. Comparison date is 2011-06-16 08:00:00. We're seeing if it's in a 5 hour interval, which in this case it is - 25 hours later. So I would do timediff(comparison_date, start_date) which returns 25:00:00. I could then do HOUR('25:00') which returns 25, which I can then mod 5. Hm! But, it doesn't seem to work for longer distances. Changing start date to be in 2010 gives me 838 hours. Golbez fucked around with this message at 22:21 on Jun 9, 2011 |
# ? Jun 9, 2011 22:19 |
|
That would work if you don't care about the minutes matching. If you do it that way, 16:00:00 means the same as 16:59:59. Also I think the maximum value for a MySQL time type is 838:59:59. e: I suppose a workaround for this would be ((datediff(date1,date2) * 24)+hour(timediff(date1,date2))) butt dickus fucked around with this message at 22:28 on Jun 9, 2011 |
# ? Jun 9, 2011 22:26 |
|
Someone on SO suggested TIMESTAMPDIFF() in MySQL which appears to be exactly what I want - I can give it the right interval, and then simply mod that based on the number of intervals I want.
|
# ? Jun 9, 2011 22:28 |
|
I have a very basic form that sends me an email of what's entered. I have two other fields I need sent to me called 'company' and 'filename'. How would I include them in this? Tried a few things but what got processed as the 'email' and 'name' were not right. Right now this is working I just want to add those two fields. Bonus points if I can have it sent to me in a way where it's displayed, Company: ['company'] File name: ['filename'] Description: ['message'] Can provide more code but this should be all you need. Thanks in advance! php:<? mail('myemail@email.com', 'New File Uploaded!', $values['message'], "From: \"{$values['name']}\" <{$values['email']}>");?>
|
# ? Jun 10, 2011 17:13 |
|
Bearnt! posted:I have a very basic form that sends me an email of what's entered. I have two other fields I need sent to me called 'company' and 'filename'. How would I include them in this? Tried a few things but what got processed as the 'email' and 'name' were not right. Right now this is working I just want to add those two fields. Bonus points if I can have it sent to me in a way where it's displayed, What did you try? Assuming you want to attach a file to your e-mail, here's Google's first result which describes how to set the appropriate headers required for the file. If you literally just want to append the string values of company and file name, you would do that with string concatenation: php:<?php $values['message']."<br>Company: ".$values['company']."<br>Filename: ".$values['company'] ?>
|
# ? Jun 10, 2011 18:06 |
|
Actually it's just for clients to fill out the info and then they are redirected to our web uploader so we know which files belong to who. I am going to read more on that link you posted, looks like some good information and I want to try this out for personal use. Anyways that worked out quite nicely, thank you! My downfall was not knowing the correct way to code more fields so I just had tried different variations in there like: php:<? $values['message'],['company'],['filename']?> php:<? $values['message'],$values['company']?> edit: nevermind \n did the trick! Bearnt! fucked around with this message at 19:23 on Jun 10, 2011 |
# ? Jun 10, 2011 18:47 |
|
Doctor rear end in a top hat posted:Are you getting every single item from your database, storing it in a variable and then using PHP to search through it? This doesn't seem like a good solution. You'd be better off with a simple php:<? function get_results() { $mysqli = new mysqli( $dbhost, $dbuser, $dbpass, $dbbase ); $keyword = $_POST['keyword']; $source = $_POST['source']; $version = $_POST['version']; if (isset($keyword)) { $result = $mysqli->query( "SELECT name, source, version FROM items WHERE name LIKE '%{$keyword}%'" ); } elseif (isset($source)) { $result = $mysqli->query( "SELECT name, source, version FROM items WHERE source = '$source'" ); } elseif (isset($version)) { $result = $mysqli->query( "SELECT name, source, version FROM items WHERE version = '$version'" ); } else { $result = $mysqli->query( "SELECT name, source, version FROM items" ); } while ( $item = $result->fetch_object() ) { echo '<tr>' . ' <td>' . $item->name . '</td>' . ' <td>' . $item->source . '</td>' . ' <td>' . $item->version . '</td>' . '</tr>'; } $result->close(); $mysqli->close(); } ?> code:
|
# ? Jun 12, 2011 06:14 |
|
Beyond the obvious SQL injection issues there, I must apologize in that I have no clue what you're trying to accomplish.
|
# ? Jun 12, 2011 06:24 |
|
Golbez posted:I must apologize in that I have no clue what you're trying to accomplish. Example values: 1, Aedirnian Leather Jacket, def_item_armor.xml, 1.2 I have a form with one input box for keywords and two dropdown fields for the source and version columns. There is an update button that runs the database queries. The dropdown menus are populated from the database. Only the keyword search works. The source and version searches do not. (I haven't yet reached the point where the keywords, source, and version fields can be combined for a single query.) Adraeus fucked around with this message at 07:00 on Jun 12, 2011 |
# ? Jun 12, 2011 06:57 |
|
Black Eagle posted:I have a database with four columns: id, name, source, and version. isset($keyword) checks whether $keyword exists and isn't null. It sounds like you're submitting it as a text form field. In that case even if you don't supply any information there it's going to be a string. So isset() will return true. I suggest changing if (isset($keyword)) to something like if (!empty($keyword) and trim($keyword) !== '') empty() is more discriminating than isset(). The second part checks that $keyword does not consist of just whitespace. Also, echoing Golbez, your code is vulnerable to SQL injection and needs to be fixed before you put it into use.
|
# ? Jun 12, 2011 08:32 |
|
All right. Now searching by keyword and source works, but only 0 works for version.php:<? $keyword = addslashes($_POST['keyword']); $source = addslashes($_POST['source']); $version = addslashes($_POST['version']); if ( !empty($keyword) && trim($keyword) !== '' ) { $result = $mysqli->query( "SELECT name, source, version FROM items WHERE name LIKE '%{$keyword}%'" ); } elseif ( !empty($source) && trim($source) !== '----' ) { $result = $mysqli->query( "SELECT name, source, version FROM items WHERE source = '$source'" ); } elseif ( isset($version) ) { $result = $mysqli->query( "SELECT name, source, version FROM items WHERE version = '$version'" ); } else { $result = NULL; } ?>
|
# ? Jun 12, 2011 09:35 |
|
|
# ? May 16, 2024 12:46 |
|
Don't use addslashes(). Also, totally unrelated, I gave a speech yesterday at the Lone Star PHP conference on unit testing and dependency injection. The video isn't online yet, but here are my slides: Unit Testing and Dependency Injection
|
# ? Jun 12, 2011 12:16 |