我正在学习一些PHP,并试图创建一个表单来更新图像并将其名称设置为"img".$_POST['something']."jpg"
,但是结果始终是img.jpg
。
我知道$_POST['something']
有一个值,因为我正在使用它在同一页面中运行查询。
我花了一整天(今天)试图弄清楚这一点,但是到目前为止我已经没有想法了。请帮忙。
我使用msqli_fetch_array
的方式可能有问题(我说是由于警告),我试图进行更改,但不确定如何。
在代码中产生了很多回声之后,我发现当我单击提交时,页面的一部分会重新加载新的$_POST
变量,这就是为什么我的postedId
消失在这一点..这有意义吗?我该如何解决?
<?php
/* Displays user information and some useful messages */
require 'db.php';
session_start();
// Check if user is logged in using the session variable
if ($_SESSION['logged_in'] != 1) {
$_SESSION['message'] = "You must log in before viewing your profile page!";
header("location: error.php");
}
$postedId = $_POST['stid'];
$result = mysqli_query($mysqli, "SELECT stcontents.id, `st_id`, `name` FROM `students`, `stcontents` WHERE stcontents.tc_id = ".$_SESSION['tcid']." AND students.id = st_id AND st_id = ".$postedId." GROUP BY st_id");
$row = mysqli_fetch_array($result);
?>
<!doctype html>
<html lang="en">
<body>
<div class="container" id="turma-container">
<form action="" method="post" enctype="multipart/form-data">
<p>Image:</p>
<input type="file" name="fileToUpload" id="fileToUpload">
<input type="submit" value="Upload Image" name="submit">
</form>
<?php
$target_dir = "resources/images/";
$target_file = $target_dir."img".$postedId.".jpg";
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
$check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
if($check !== false) {
echo "File is an image - " . $check["mime"] . ".";
$uploadOk = 1;
} else {
echo "File is not an image.";
$uploadOk = 0;
}
}
// Check file size
if ($_FILES["fileToUpload"]["size"] > 500000) {
echo "Sorry, your file is too large.";
$uploadOk = 0;
}
// Allow certain file formats
if($imageFileType != "jpg") {
echo "Sorry, only JPG files are allowed.";
$uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
echo "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
} else {
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded.";
} else {
echo "Sorry, there was an error uploading your file.";
}
}
?>
</div>
</body>
</html>
我期望生成的文件名类似于img6.jpg,而不是img.jpg。这是我得到的日志
[2019年7月19日23:41:27 UTC] PHP注意:未定义的索引:fileToUpload 在第46行的/home/[...]/myfolder/myfile.php中[2019年7月19日23:41:27 [UTC] PHP注意:未定义的索引:fileToUpload /home/[...]/myfolder/myfile.php,第60行[19-Jul-2019 23:41:33 UTC] PHP注意:未定义的索引:固定在/home/[...]/myfolder/myfile.php中 在线12 [19-Jul-2019 23:41:33 UTC] PHP警告: mysqli_fetch_array()期望参数1为mysqli_result,布尔 在第16行的/home/[...]/myfolder/myfile.php中给出
答案 0 :(得分:0)
首先,我要感谢向我发送提示并花时间阅读我的代码的每个人。我进行了更改,但仍无法按预期进行。
正如我所说,借助ArendE的技巧,我在代码中进行了很多更改,现在我认为它变得更加有意义(我认为我也可以更好地理解它)。 我要更改的一件事是使它更加完整,不仅可以选择上传图像,还可以添加/更改文本并查看图像(如果图像已经上传)。 不幸的是,某些东西仍然无法正常工作。发布代码时,我会尽力解释。
每个id变量都是一个int,初始$ _POST来自另一个页面中的按钮。
顶级php,在这里建立连接并声明一些变量:
<?php
/* Displays user information and some useful messages */
session_start();
require 'db.php';
// Check if user is logged in using the session variable
if (empty($_SESSION['logged_in'] != 1) {
$_SESSION['message'] = "You must log in before viewing your profile page!";
header("location: error.php");
exit();
}
else {
// Makes it easier to read
$name = $_SESSION['name'];
}
if (isset($_POST['stid'])) {
$pstid = $_POST['stid'];
$result = mysqli_query($link, "SELECT `id`, `tc_id`, `name`, `essay`, `image` FROM `students` WHERE tc_id = ".$tcid." AND id = ".$pstid.";");
$row = mysqli_fetch_array($result);
$stname = $row['name'];
$cessay = $row['essay'];
$cimage = $row['image'];
}
?>
一些html,我在这里创建文本字段(如果数据库中有文本,则已经包含文本),显示图像(如果仍然存在),并提供一个上载图像选项来更改/添加它。如果用户更改了文字或图像,则会单击“保存”按钮。
<form method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="TextToUpload">Text:</label>
<textarea type="text" class="form-control" id="TextToUpload" rows="5" name="stessay"><?php echo $cessay; ?></textarea>
</div>
<p>Imagem do(a) aluno(a):</p>
<?php
if (isset($row['image'])) {
echo "<img src=\"resources/images/studentsImages/".$cimage."\">";
}
echo "<input type=\"hidden\" name=\"stid\" value=".$pstid.">";
?>
<input type="file" name="fileToUpload" id="fileToUpload">
<input formmethod="post" type="submit" value="savechanges" name="submit">
</form>
和底部php。在这里,我检查是否有文本和/或是否选择了要更新的文件。进行了一些检查,好像文件已损坏,我尝试将它们都发送出去。
<?php
if(isset($_POST["submit"])) {
$essayOk = 0;
$imageOk = 0;
if(isset($_POST['stessay'])) {
$essayOk = 1;
$pessayc = mysqli_real_escape_string($link, $_POST['stessay']);
}
if (isset($_POST['fileToUpload'])) {
$target_dir = "resources/images/";
$target_file = $target_dir."img".$pstid.".jpg";
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// Check if image file is a actual image or fake image
if($mime = finfo_file($finfo, $target_dir . $_FILES["fileToUpload"]["tmp_name"])) {
if($mime == 'image/jpg' || $mime == 'image/jpeg') {
if(getimagesize($target_dir . $_FILES["fileToUpload"]["tmp_name"]) === false) {
echo "File is corrupt";
$uploadOk = 0;
} else {
echo "File is an image - " . $mime . ".";
$uploadOk = 1;
}
} else {
echo $mime . " is not supported.";
$uploadOk = 0;
}
} else {
echo "Invalid file";
$uploadOk = 0;
}
// Check file size
if ($_FILES["fileToUpload"]["size"] > 500000) {
echo "The file is too big.";
$imageOk = 0;
}
// Check if $imageOk is set to 0 by an error
if ($imageOk == 0) {
echo "Erros sending image, try again later.";
// if everything is ok, try to upload file
}
}
if ($essayOk == 1) {
$query = "UPDATE students SET essay = '".$pessayc."' WHERE id = '".$pstid."';";
if (mysqli_query($link, $query)) {
echo "<p>Essay updated!</p>";
} else {
printf("Errormessage: %s\n", mysqli_error($link));
echo "<p>There was an error updating the ssay, try again later.</p>";
}
}
if ($imageOk == 1) {
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
echo "The file ".basename($_FILES["fileToUpload"]["name"])." was updated.";
} else {
echo "Your image was not updated, try again later.";
}
}
}
?>
我认为问题出在代码的底部php部分,由于某种原因(我不知道),好像isset($ _ POST ['fileToUpload'])每次都返回false,即使选择了文件。 ir不应该随身携带,stid和提交吗?这次,error_log上绝对没有任何内容。 $ _POST的print_r仅返回Array([stessay] => Test [stid] => 1 [submit] => savechanges) 为什么还没有fileToUpload?
答案 1 :(得分:-1)
您已经花了一整天的时间了,让我给您提供一些建议。我希望您可以从中学到一些东西,并理解为什么那些“未定义”和“通知”在那里。我尚未测试代码,但是如果您浏览所有注释,希望您能理解并能够使它开始工作。
<?php
// Always start sessions first:
// if your db.php throws an error, the session can't start anymore
// and throws a warning
session_start();
require('db.php');
// Do check if a variable exists. PHP should throw you a warning otherwise.
if(empty($_SESSION['logged_in']) || $_SESSION['logged_in'] != 1) {
$_SESSION['message'] = "You must log in before viewing your profile page!";
header("Location: error.php");
// Stop running the script after a redirect!
// A header is an instruction, a client
// might simple ignore it and show the page content anyway
exit();
}
// Check if the variable exists!
// Long way:
// if(isset($_POST['stid'])) { $postedId = $_POST['stid'] } else { $postedId = false; }
// Medium way:
// $postedId = (isset($_POST['stid']) ? $_POST['stid'] : false;
// Short way:
$postedId = $_POST['stid']?:false;
// Make your query look nice, makes your life easy and debugging too
// Query questions:
// 1. What if $_SESSION['tcid'] doesn't exist?
// 2. What if $postedId doesn't exist?
// 3. What if $postedId is 0; DROP TABLE students; ?
// Remember, a client can send anything via $_POST['stid']
//
//$qry = "SELECT stcontents.id, `st_id`, `name`
// FROM `students`, `stcontents`
// WHERE stcontents.tc_id = " . $_SESSION['tcid'] . "
// AND students.id = st_id
// AND st_id = " . $postedId . " GROUP BY st_id";
//
// Read about mysqli_real_escape_string
// https://www.php.net/manual/en/mysqli.real-escape-string.php
// Want to do it really right? Use prepared statements
// https://www.php.net/manual/en/mysqli.prepare.php
$qry = "SELECT stcontents.id, `st_id`, `name`
FROM `students`, `stcontents`
WHERE stcontents.tc_id = " . mysqli_real_escape_string($mysqli, $_SESSION['tcid']) . "
AND students.id = st_id
AND st_id = " . mysqli_real_escape_string($mysqli, $postedId) . " GROUP BY st_id";
$result = mysqli_query($mysqli, $qry);
$row = mysqli_fetch_array($result);
// But what if no result was found?
if(empty($postedId) || empty($row)) {
exit('Something above went wrong!');
}
?>
<!doctype html>
<html lang="en">
<body>
<div class="container" id="turma-container">
<!--
// Leave out the action if it's empty anyway
// https://stackoverflow.com/questions/1131781/is-it-a-good-practice-to-use-an-empty-url-for-a-html-forms-action-attribute-a
-->
<form method="post" enctype="multipart/form-data">
<p>Image:</p>
<input type="file" name="fileToUpload" id="fileToUpload">
<input type="submit" value="Upload Image" name="submit">
</form>
<?php
$target_dir = "resources/images/"; // Better use the full path
// $target_file = $target_dir."img".$postedId.".jpg";
// What if $postedId is /../../logo ?
// Is resources/images/img/../../logo.jpg a valid path?
//
// I'll assume $postedId will be an integer (number)
// using https://www.php.net/manual/en/function.settype.php
settype($postedId, 'int');
// Another approach: basename()
// https://www.php.net/manual/en/function.basename.php
// https://www.php.net/manual/en/features.file-upload.post-method.php
$target_file = $target_dir . basename("img" . $postedId . ".jpg");
$uploadOk = 1;
// $imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// You have just made a string $target_file.. so
// nothing is there, or it would be jpg anyway, since you've said ".jpg"
if(isset($_POST["submit"])) {
// So $_POST['submit'] might be there, but was the fileToUpload too?
if(empty($_FILES["fileToUpload"])) {
exit('no file!');
}
// $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
//
// Well although getimagesize indeed does return false on failure,
// read the caution "Do not use to check that a given file is a valid image."
// here https://www.php.net/manual/en/function.getimagesize.php
// the path it also incomplete ($target_dir is missing)
$finfo = finfo_open(FILEINFO_MIME_TYPE);
if($mime = finfo_file($finfo, $_FILES["fileToUpload"]["tmp_name"])) {
if($mime == 'image/jpg' || $mime == 'image/jpeg') {
// Now you could use getimagesize as extra check
// But there might be better alternatives
if(getimagesize($_FILES["fileToUpload"]["tmp_name"]) === false) {
echo "File is corrupt";
$uploadOk = 0;
} else {
echo "File is an image - " . $mime . ".";
$uploadOk = 1;
}
} else {
echo $mime . " is not supported.";
$uploadOk = 0;
}
} else {
echo "Invalid file";
$uploadOk = 0;
}
if($_FILES["fileToUpload"]["size"] > 500000) {
echo "Sorry, your file is too large.";
$uploadOk = 0;
}
// if($imageFileType != "jpg") {
// echo "Sorry, only JPG files are allowed.";
// $uploadOk = 0;
// }
//
// Done this above.
// If the idea is some pre-flight check, consider $_FILES['fileToUpload']['type']
if($uploadOk == 0) {
echo "Sorry, your file was not uploaded.";
} else {
if(move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
echo "The file ". basename($_FILES["fileToUpload"]["name"]). " has been uploaded.";
} else {
echo "Sorry, there was an error uploading your file.";
}
}
}
?>
</div>
</body>
</html>
仍然可以进行很多优化,但这应该可以帮助您。祝你好运!如果您有任何疑问,请随时发表评论。
发表评论后,让我们开始新一轮! 再次是下面的代码:
<?php
session_start();
require 'db.php';
// So empty($var) returns true/false based on if a variable exists (isset()) and it's value
// Read: https://www.php.net/empty what is considered FALSE is it exists
// I'm guessing this will do:
if (empty($_SESSION['logged_in'])) {
$_SESSION['message'] = "You must log in before viewing your profile page!";
header("location: error.php");
exit();
} else {
// If you are sure $_SESSION['name'] exists if a user is logged in, this is fine.
// Otherwise consider $name = $_SESSION['name']?:'unknown';
$name = $_SESSION['name'];
}
if (isset($_POST['stid'])) {
// So you still allow a raw POST variable in your database query..
// Don't do that or you might find someone messed around with your database.
// https://www.w3schools.com/sql/sql_injection.asp
// $pstid = $_POST['stid'];
$pstid = mysqli_real_escape_string($link, $_POST['stid']);
$tcid = mysqli_real_escape_string($link, $tcid); // Where does $tcid come from? Does it exist?
// Check if the query is succesful and if there are results..
// In the function documentation always peek at the Parameters and Return Values
// https://php.net/manual/en/mysqli.query.php : Returns FALSE on failure.
// https://www.php.net/manual/en/mysqli-result.fetch-array.php : Returns NULL if there are no more rows
if($result = mysqli_query($link, "SELECT `id`, `tc_id`, `name`, `essay`, `image` FROM `students` WHERE tc_id = ".$tcid." AND id = ".$pstid.";")) {
if($row = mysqli_fetch_array($result)) {
$stname = $row['name'];
$cessay = $row['essay'];
$cimage = $row['image'];
} else {
$_SESSION['message'] = "No essay was found, please create one first.";
header("location: error.php");
exit();
}
} else {
$_SESSION['message'] = "Something went wrong..";
header("location: error.php");
exit();
}
// What if $_POST['stid'] does not exist though?
// You use it as hidden input for your form, so let's throw an error.
} else {
$_SESSION['message'] = "Student id not found.";
header("location: error.php");
exit();
}
?>
<form method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="TextToUpload">Text:</label>
<!--
So, $cessay comes from your database; but how does it get entered? By students?
Imagine a students enters "</textarea><img src="https://i.imgur.com/BBcy6Wc.jpg">"
Right.. a cat picture will be shown.. Solution: Escape it.
https://www.w3schools.com/php/func_string_htmlspecialchars.asp
So:
-->
<textarea type="text" class="form-control" id="TextToUpload" rows="5" name="stessay"><?php echo $cessay; ?></textarea>
</div>
<p>Imagem do(a) aluno(a):</p>
<?php
if (isset($row['image'])) {
// Same applies here, although cimage might be under your control, so less critical
// Just make it a habbit to escape and you'll never have trouble :)
$cimage = htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
echo "<img src=\"resources/images/studentsImages/".$cimage."\">";
}
// So I've used it before in mysqli_real_escape_string, so it now could be something like '123' instead of 123
// Since we now need to escape it not for SQL but HTML, just use the original value again:
echo "<input type=\"hidden\" name=\"stid\" value=".htmlspecialchars($_POST['stid'], ENT_QUOTES, 'UTF-8').">";
?>
<input type="file" name="fileToUpload" id="fileToUpload">
<input formmethod="post" type="submit" value="savechanges" name="submit">
</form>
<?php
if(isset($_POST["submit"])) {
$essayOk = 0;
$imageOk = 0;
if(isset($_POST['stessay'])) {
$essayOk = 1;
$pessayc = mysqli_real_escape_string($link, $_POST['stessay']);
// Very good! :)
}
// Uploaded files should be in the $_FILES array! So don't use $_POST
if (isset($_FILES['fileToUpload'])) {
$target_dir = "resources/images/";
$target_file = $target_dir."img".$pstid.".jpg";
// $imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION)); // Not needed, fails anyway
// But where is $finfo ? The code below will always fail without it..
// Adding it back:
$finfo = finfo_open(FILEINFO_MIME_TYPE);
if($mime = finfo_file($finfo, $_FILES["fileToUpload"]["tmp_name"])) {
if($mime == 'image/jpg' || $mime == 'image/jpeg') {
if(getimagesize($_FILES["fileToUpload"]["tmp_name"]) === false) {
echo "File is corrupt";
$uploadOk = 0;
} else {
echo "File is an image - " . $mime . ".";
$uploadOk = 1;
}
} else {
echo $mime . " is not supported.";
$uploadOk = 0;
}
} else {
echo "Invalid file";
$uploadOk = 0;
}
if ($_FILES["fileToUpload"]["size"] > 500000) {
echo "The file is too big.";
$imageOk = 0;
}
if ($imageOk == 0) {
echo "Erros sending image, try again later.";
}
}
if ($essayOk == 1) {
$query = "UPDATE students SET essay = '".$pessayc."' WHERE id = '".$pstid."';";
if (mysqli_query($link, $query)) {
echo "<p>Essay updated!</p>";
} else {
printf("Errormessage: %s\n", mysqli_error($link));
echo "<p>There was an error updating the ssay, try again later.</p>";
}
}
if ($imageOk == 1) {
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
echo "The file ".basename($_FILES["fileToUpload"]["name"])." was updated.";
} else {
echo "Your image was not updated, try again later.";
}
}
}
?>
关于您的最后一个问题,请检查它是否存在于$_FILES
数组中,但我也相信文件名仍应位于$_POST
数组中。虽然不确定。将其添加到代码顶部,以查看找到了哪些变量:
print_r($_POST);
print_r($_FILES);
它将为您提供一个不错的POST字段和上传文件列表。