繁体   English   中英

PHP - 由于上传路径,文件上传失败并使用相关路径保存

[英]PHP - File upload failed due to upload path and save with related path

项目文件夹结构:

工作

  • 图片
    • 验证.php

以下是validate.php中的代码

<?php

    include('config.php');
    $_SESSION['message'] = '';

    // REGISTER CANDIDATES
    if(isset($_POST['register'])){

        if($_POST['password'] == $_POST['confirmpassword']){

            $fullname       = $_POST['fullname'];
            $phone          = $_POST['phone'];
            $username       = $_POST['username'];
            $email          = $_POST['email'];
            // $pass           = md5($_POST['password']);
            $pass           = password_hash( $_POST['password'], PASSWORD_DEFAULT );
            $dirname        = dirname(__DIR__) . '/images/'; // this works
            $temp           = explode(".", $_FILES['avatar']['name']);
            $newfilename    = round(microtime(true)) . '.' . end($temp);
            $avatar_path    = $dirname . $newfilename;
            // $avatar_path    = '../images/' . $_FILES['avatar']['name'];

            $fullname       = mysqli_real_escape_string($conn,$fullname);
            $phone          = mysqli_real_escape_string($conn,$phone);
            $username       = mysqli_real_escape_string($conn,$username);
            $email          = mysqli_real_escape_string($conn,$email);
            $avatar_path    = mysqli_real_escape_string($conn,$avatar_path);

            if(preg_match("!image!", $_FILES['avatar']['type'])){

                if(copy($_FILES['avatar']['tmp_name'],$avatar_path)){
                    $_SESSION['username']   = $username;
                    $_SESSION['avatar']     = $avatar_path;

                    $sql = "INSERT INTO candidates (fullname, phone, username, email, pass, avatar) VALUES('$fullname','$phone','$username','$email','$pass', '$avatar_path')";

                    if(mysqli_query($conn,$sql)){
                        $_SESSION['message'] = "Registration Successful!";
                        header("location:user.php");
                    } else {
                        $_SESSION['message'] = "User could not be added!";
                    }
                } else {
                    $_SESSION['message'] = "File Upload Failed!";
                }
            } else {
                $_SESSION['message'] = "Please upload only JPG, PNG or GIF image!";
            }

        } else {
            $_SESSION['message'] = "Password did not match!";
        }
    }



    // LOGIN CANDIDATES
    if (isset($_POST['login'])) {
        $username   = mysqli_real_escape_string($conn, $_POST['username']);
        $password   = mysqli_real_escape_string($conn, $_POST['password']);

        if (empty($username)) {
            $_SESSION['message'] = "Username or email is required";
        }
        if (empty($password)) {
            $_SESSION['message'] = "Password is required";
        }

        if (!empty($username) && !empty($password)) {
            $password = md5($password);
            $query = "SELECT * FROM candidates WHERE username='$username' AND pass='$password'";
            $results = mysqli_query($conn, $query);

            if (mysqli_num_rows($results) == 1) {
                $_SESSION['username'] = $username;
                $_SESSION['message'] = "You are now logged in";
                header('location: user.php');
            } else {
                $_SESSION['message'] = "Wrong username/password combination";
            }
        }
    }

?>

以下几行的问题,

$dirname        = dirname(__DIR__) . '/images/';
$avatar_path    = $dirname . $_FILES['avatar']['name'];

它保存路径,如/home/rainpeyi/public_html/demo/jobs/images/Nisha.jpg这不适用于img src="" 我想要检索图像的相对路径。 如果我们可以保存像 www.example.com/project-dir/images/img.name 这样的路径,那就太好了

形式如下:

<?php 
    include('lib/validate.php');

    // header
    include('inc/header.php');
?>

<div class="register_form">
    <h2>Create an account</h2>
    <form class="form" action="register.php" method="post" enctype="multipart/form-data" autocomplete="off">
        <div class="alert alert-error"><?= $_SESSION['message'] ?></div>
            <div class="group_row">
                <div class="fullname">
                    <label for="fullname">Full Name:</label>
                    <input type="text" placeholder="Anwer Ashif" name="fullname" required />
                </div>
                <div class="tel">
                    <label for="phone">Mobile or Telephone:</label>            
                    <input type="tel" placeholder="01812-345678" name="phone" required />
                </div>
            </div>
        <div class="group_row">
            <div class="username">
                <label for="username">Username:</label>
                <input type="text" placeholder="ashif" name="username" required />
            </div>
            <div class="email">
                <label for="email">Email:</label>
                <input type="email" placeholder="myemail@example.com" name="email" required />
            </div>
        </div>
        <div class="group_row">
            <div class="password">
                <label for="password">Password:</label>
                <input type="password" placeholder="ue$jL382@0l" name="password" autocomplete="new-password" required />
            </div>
            <div class="reenterpass">
                <label for="confirmpassword">Confirm Password:</label>
                <input type="password" placeholder="ue$jL382@0l" name="confirmpassword" autocomplete="new-password" required />
            </div>
        </div>
        <div class="avatar out-group">
            <label>Select your avatar: </label>
            <input type="file" name="avatar" accept="image/*" required />
        </div>
        <input type="submit" value="Register" name="register" class="btn btn-block btn-primary" />
        <p>
            Already a member? <a href="login.php">Sign in</a>
        </p>
    </form>
</div>

<?php
    include('inc/footer.php');
?>

任何帮助将不胜感激:)

$dirname = dirname(__DIR__) . '/images/';`enter code here`

将其替换为

$dirname ='../images/';

或者

$dirname = 'example.com/project-dir/images/';

我玩了一会儿-也许这可能对您有所帮助。 我确实对此进行了测试,在这里一切都很好。 需要注意的几点:- 不要尝试使用MD5对用户的密码进行 hash - 它已被认为"broken"了好几年,并且有大量已知哈希的字典可用于识别密码。 此外 - 尽管使用mysqli_real_escape_string仍然存在 SQL 由于嵌入变量而注入的潜在危险,并且mysqli_real_escape_string也可能会修改某些字符串的值,这可能会使事情变得有些复杂,因此建议您使用带有绑定变量的prepared statements

代码中的注释也可能有所帮助。

<?php


    try{
        /*
            it is more important to know whether or not the fields that are used
            in the SQL are present in the POST array than it is to know if the
            button has been pressed. It is possible to bypass the form afterall!
        */
        if( isset(
            $_POST['fullname'],
            $_POST['phone'],
            $_POST['username'],
            $_POST['email'],
            $_POST['password'],
            $_POST['confirmpassword']
        )){
            if( $_POST['password']!==$_POST['confirmpassword'] )throw new Exception('Passwords do not match');

            require 'config.php';

            $root=$_SERVER['DOCUMENT_ROOT'];
            $tmp=!empty( $_FILES['avatar'] ) ? $_FILES['avatar']['tmp_name'] : false;
            $name=!empty( $_FILES['avatar'] ) ? $_FILES['avatar']['name'] : false;
            $exts=['gif','png','jpg','jpeg'];


            if( $tmp && $name ){

                $ext=strtolower( pathinfo( $name, PATHINFO_EXTENSION ) );
                if( !in_array( $ext, $exts ) )throw new Exception( sprintf('The file extension "%s" is not allowed', $ext ) );
                if( !getimagesize( $tmp ) ) throw new Exception( sprintf('"%s" does not appear to be an image', $name ) );



                # The "Current Working Directory" is "/demo/jobs/lib/"
                # so the "images" folder is a level UP at "/demo/jobs/images"
                chdir( '../' );
                $cwd=getcwd();


                # The path used to save/move uploaded file
                # & should yield a path of the form:
                # /home/rainpeyi/public_html/demo/jobs/images/filename.jpg          
                $savepath = sprintf( '%s/images/%s', $cwd, $name );



                # The path to the `demo/jobs` folder
                $apppath =  str_replace( 
                                array( realpath( $root ), DIRECTORY_SEPARATOR ),
                                array( '', '/' ),
                                realpath( $cwd )
                            );

                # & should yield a path of the form:
                # /demo/jobs/images/filename.jpg
                $displaypath = sprintf( '%s/images/%s', $apppath, $name );



                if( is_object( $conn ) && is_uploaded_file( $tmp ) && move_uploaded_file( $tmp, $savepath ) ){
                    # safe sql statement with placeholders
                    $sql='insert into `candidates` 
                            ( `fullname`, `phone`, `username`, `email`, `pass`, `avatar` ) 
                        values 
                            ( ?, ?, ?, ?, ?, ? )';

                    #MD5 is broken.. do NOT use for password hashing, ever!
                    $hash=password_hash( $_POST['password'], PASSWORD_DEFAULT );

                    # create the `prepared statement` object & bind variables to placeholders
                    $stmt=$conn->prepare( $sql );
                    $stmt->bind_param('ssssss', $_POST['fullname'], $_POST['phone'], $_POST['username'], $_POST['email'], $hash, $displaypath );

                    $result=$stmt->execute();
                    $rows=$stmt->affected_rows;

                    if( !$result or $rows==0 )throw new Exception( 'Unable to add user' );
                    else {
                        # all good.. user added, image saved
                        # redirect user

                        session_start();
                        $_SESSION['message'] = "Registration Successful!";

                        exit( header('Location: user.php') );
                    }
                }else{
                    throw new Exception('File upload failed');
                }
            }else{
                throw new Exception('Bad foo! No file present');
            }
        }else{
            $tmp=[];
            $fields=array(
                'fullname',
                'phone',
                'username',
                'email',
                'password',
                'confirmpassword'
            );
            foreach( $fields as $field ){
                if( !in_array( $field, array_keys( $_POST ) ) )$tmp[]=$field;
            }
            throw new Exception( sprintf( 'One or more required fields are not present in the POST request!<br />%s', implode( '<br />', $tmp ) ) );
        }
    }catch( Exception $e ){
        exit( $e->getMessage() );
    }
?>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM