PHP file wants to download instead of opening

epiz_28063674
Website URL – michaelsbookcorner.com

I’ve just uploaded a file called dataControl.php to my root directory. Typing in https://michaelsbookcorner.com/dataControl.php the file wants to download rather than opening. All of my other .php files and functions on the website are loading functioning normally – interacting with the database and with APIs. The file also opens/displays in localhost just fine – so it can open.

I’ve loaded several other PHP file and run into this on my localhost. There was fix with the php.ini file, but I do not know if this is a problem on the hosting site. How to go about fixing this problem?

What are the contents of the file? Are there any Headers (specifically ones that set Content-Type or Content-Disposition)?

There are no headers in this file. I am reusing some php functionality I’m using successfully in other .php/html file with no issues.

Can you share the contents of the file?
I have checked the headers and indeed there is a Content-Disposition: attachment being set, and this is why it is being downloaded.

2 Likes

The server side stuff is pretty new to me. I thought the headers had to be set explicitly by me and I don’t believe I’ve set any in the code. I"d be happy to learn how that works…

*****************************************************************`

<?php

    include ('loadenv.php');

    ini_set('display_errors', '0');

    // BEGIN newBlog to upload a new blog into the blogPosts table
    function newBlog($ptitle, $pdateFancy, $pdatePlain, $pauthor, $ptopic, $pabstract, $pkeyword1, $pkeyword2,
    $pkeyword3,$pkeyword4, $pkeyword5, $pthumbURL, $ppostFile, $ppostURL) {
        
    include ('db.php');
  
    $sql = "INSERT INTO blogPosts (title, dateFancy, datePlain, author, topic, abstract, keyword1, keyword2, keyword3, keyword4, keyword5, thumbURL, postFile, postURL)
    VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
    $stmt = $db->prepare($sql);
    // Bind our params */
  // BK: variables must be bound in the same order as the params in your SQL.
    $stmt->bind_param('ssssssssssssss', $ptitle, $pdateFancy, $pdatePlain, $pauthor, $ptopic, $pabstract, $pkeyword1, $pkeyword2,
    $pkeyword3,$pkeyword4, $pkeyword5, $pthumbURL, $ppostFile, $ppostURL);
    /* Execute the prepared Statement */
    $stmt->execute();
   
    $db->close();
  
    
  }
  // END newBlog to upload a new blog into the blogPosts table

    // BEGIN checkpaySatus() for checking progress of transaction
  function getStatus($ppayment_id) {
    $curl = curl_init();

    curl_setopt_array($curl, array(
    CURLOPT_URL => 'https://api.nowpayments.io/v1/payment/'.$ppayment_id,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => array(
        'x-api-key: '.$_ENV['NOWPAYMENTS_API_KEY']
    ),
    ));

        $response = curl_exec($curl);

        curl_close($curl);
        $returnData = json_decode($response,true);
    //    echo $response;
    //    echo "<br>";
    //    var_dump($returnData);
        
        return $returnData;

  }
// END checkpaySatus() for checking progress of transaction

  // BEGIN verifyPaymentID() to check validity of payment_id in websiteData
  function verifyPayment($ppayment_id) {
          
    include ('db.php');

    $sql = "SELECT * FROM payments WHERE payment_id=?";
    $stmt = $db->prepare($sql);
    // Bind our params */
  // BK: variables must be bound in the same order as the params in your SQL.
    $stmt->bind_param('s', $ppayment_id);
    /* Execute the prepared Statement */
    $stmt->execute();
    $result = $stmt->get_result(); // get the mysqli result
    $data = $result->fetch_assoc(); // fetch data

    $db->close();
    $order[0] = $data['payment_status'];
    $order[1] = $data['order_description'];
    $order[2] = $data['email'];
    
    return $order;
    
  }
  // END verifyPaymentID() to check validity of payment_id in websiteData

  // BEGIN updateStatus() to update payment status in database table
  function updateStatus($ppayment_id, $pstatus) {
          
    include ('db.php');

    $sql = "UPDATE payments SET payment_status = ? WHERE payment_id=?";
    $stmt = $db->prepare($sql);
    // Bind our params */
  // BK: variables must be bound in the same order as the params in your SQL.
    $stmt->bind_param('ss', $ppayment_id, $pstatus);
    /* Execute the prepared Statement */
    $stmt->execute();
  
    $db->close();

    
  }
// END updateStatus() to update payment status in database table

  if(isset($_POST['new_blog_entry'])) {

    $title = $_POST['title'];
    $dateFancy = $_POST['dateFancy']; 
    $datePlain = $_POST['datePlain']; 
    $author = $_POST['author']; 
    $topic = $_POST['topic']; 
    $abstract = $_POST['abstract']; 
    $keyword1 = $_POST['keyword1']; 
    $keyword2 = $_POST['keyword2'];
    $keyword3 = $_POST['keyword3'];
    $keyword4 = $_POST['keyword4']; 
    $keyword5 = $_POST['keyword5']; 
    $thumb_file = $_POST['thumb_file']; 
    $post_file = $_POST['post_file'];

    $dateArray = explode('-',$datePlain);
    $year = $dateArray[0];

    $thumbURL = '../blogThumbs/'.$thumb_file;
    $postURL = $year.'/'.$post_file;

    newBlog($title, $dateFancy, $datePlain, $author, $topic, $abstract, $keyword1, $keyword2,
    $keyword3,$keyword4, $keyword5, $thumbURL, $post_file, $postURL);
    
  }

  if(isset($_POST['payment_verification'])) {
    
    $payment_id = $_POST['payment_id'];
    // Check order in MBC Database
    $order = verifyPayment($payment_id);

    $MBCPayments_status = $order['payment_status'];
    $order_description = $order['order_description'];
    $email = $order['email'];
    
    $transaction = getStatus($payment_id);
    $NOWPayments_status = $transaction['payment_status'];
  }

?>

<!DOCTYPE html>

<html>
    <head><title>Database Editor</title>

    <style>
    .center {
        text-align: center;
    }
    @import "compass/css3";

@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,600,300,800);

* {
  box-sizing: border-box;
}
html,
body {
  overflow-x: hidden;
  font-family: "Open Sans", sans-serif;
  font-weight: 300;
  color: #fff;
  background: #032429;
}
@mixin epic-sides() { // https://codepen.io/MichaelArestad/pen/qltuk
    position: relative;
    z-index: 1;

    &:before {
        position: absolute;
        content: "";
        display: block;
        top: 0;
        left: -5000px;
        height: 100%;
        width: 15000px;
        z-index: -1;
        @content;
    }
}
.row {
  max-width: 800px;
  margin: 0 auto;
  padding: 60px 30px;
  background: black;
  @include epic-sides() {background: inherit;}
  text-align: center;
  
  &:first-child {
    padding: 40px 30px;
  }
  &:nth-child(2),
  &:nth-child(8),
  &:nth-child(10){
    background: #134A46;
  }
  &:nth-child(3),
  &:nth-child(7) {
    background: #377D6A;
  }
  &:nth-child(4),
  &:nth-child(6) {
    background: #7AB893;
  }
  &:nth-child(5) {
    background: #B2E3AF;
  }
  
  span {
    position: relative;
    display: inline-block;
    margin: 30px 10px;
  }
}
.gate {
  display: inline-block;
  width: 215px;
  padding: 10px 0 10px 10px;
  font-family: "Open Sans", sans;
  font-weight: 400;
  color: #377D6A;
  background: #efefef;
  border: 0;
  border-radius: 3px;
  outline: 0;
  text-indent: 0px; // Arbitrary.
  transition: all .3s ease-in-out;
  
  &::-webkit-input-placeholder {
    color: #efefef;
    text-indent: 0;
    font-weight: 300;
  }

  + label {
    display: inline-block;
    position: absolute;
    top: 0;
    left: 0;
    padding: 15px 15px;
    text-shadow: 0 1px 0 rgba(19,74,70,.4);
    background: #7AB893;
    transition: all .4s ease-in-out;
    border-top-left-radius: 5px;
    border-bottom-left-radius: 5px;
    transform-origin: left bottom;
    z-index: 99;
    
    &:before,
    &:after {
      content: "";
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      border-radius: 3px;
      background: #377D6A;
      transform-origin: left bottom;
      transition: all .4s ease-in-out;
      pointer-events: none;
      z-index: -1;
    }
    &:before {
      background: rgba(3,36,41,.2);
      z-index: -2;
      right: 20%;
    }
  }
}
span:nth-child(2) .gate {
  text-indent: 10px;
}
span:nth-child(2) .gate:focus,
span:nth-child(2) .gate:active{
  text-indent: 0;
}
.gate:focus,
.gate:active {
  color: #377D6A;
  text-indent: 0;
  background: #fff;
  border-top-right-radius: 3px;
  border-bottom-right-radius: 3px;
  
  &::-webkit-input-placeholder {
    color: #aaa;
  }
  + label {
    transform: rotate(-66deg);
    border-radius: 3px;
    
    &:before {
      transform: rotate(10deg);
    }
  }
}
.swing:focus,
.swing:active {
  color: #377D6A;
  text-indent: 0;
  background: #fff;
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  
  &::-webkit-input-placeholder {
    color: #aaa;
  }
  + label {
    animation: swing 1.4s 1 ease-in-out;
    transform: rotate(82deg);
  }
}
.btn {
	background-color: #032429;
	color: #f3f3f3;
	text-align: center;
	font-size: 1rem;
	margin: 1rem;
	border-radius: 30px;
	width: 200px;
	height: 30px;
}
.center {
    text-align: center;
}
</style>
    
</head>

    <body>
    <h1 class="center">Michael's Book Corner</br>Database Editor</h1>
    
    <form action="dataControl.php" method="POST">
    <div class="row">
    <table>
        <!-- Header Merge All-->
        <tr>
            <th colspan="5">New Blog Entry</th>
        </tr>
        <!-- Title 3/ Post FIle_Name 1/ Thumb File_Name 1 -->
        <tr>
            <td colspan="3"><label for="title">Title: </label></br>
        <input class="gate" type="text" id="title" name="title" style="width: 400px;" placeholder="NASA Has Failed"/></td>
            <td><label for="post_file">Post File_Name: </label></br>
        <input class="gate" type="text" id="post_file" name="post_file" style="width: 150px;" placeholder="post-2025-12-17.html"/></td>
            <td><label for="thumb_file">Thumb File_Name: </label></br>
        <input class="gate" type="text" id="thumb_file" name="thumb_file" style="width: 150px;" placeholder="2025-12-17.jpeg"/></td>            
        </tr>
        <!-- -Date Fancy 3/ Date Plain 2 -->
        <tr>
            <td colspan="3"><label for="dateFancy">Formal Date: </label></br>
        <input class="gate" type="text" id="dateFancy" name="dateFancy" placeholder="December 17, 2025"/></td>
            <td colspan="2"><label for="datePlain">Plain Date: (follow format)</label></br>
        <input class="gate" type="text" id="datePlain" name="datePlain" placeholder="2025-12-17"/></td>
        </tr>
        <!-- -Author 1/ Topic 1 / Abstract 3 -->
        <tr>
            <td><label for="author">Author: (full name)</label></br>
        <input class="gate" type="text" id="author" name="author" placeholder="Michael J. Scharen"/></td>
            <td><label for="topic">Topic: </label></br>
        <input class="gate" type="text" id="topic" name="topic" style="width: 100px;" placeholder="physics"/></td>
            <td colspan="3"><label for="topic">Abstract: (Two sentences max)</label></br>
        <input class="gate" type="text" id="abstract" name="abstract" style="width: 400px;" placeholder="NASA is behind the times doing only make-work."/>
</td>
            
        </tr>
        <!-- -Keywords 1 each-->
        <tr>
            <td style="width:20%;"><label for="keyword1">KeyWord 1: </label></br>
        <input class="gate" type="text" id="keyword2" name="keyword1" style="width: 100px;" placeholder="Boeing"/></td>
            <td style="width:20%;"><label for="keyword2">KeyWord 2: </label></br>
        <input class="gate" type="text" id="keyword2" name="keyword2" style="width: 100px;" placeholder="SLS"/></td>
            <td style="width:20%;"><label for="keyword3">KeyWord 3: </label></br>
        <input class="gate" type="text" id="keyword3" name="keyword3" style="width: 100px;" placeholder="reusable"/></td>
            <td style="width:20%;"><label for="keyword4">KeyWord 4: </label></br>
        <input class="gate" type="text" id="keyword1" name="keyword4" style="width: 100px;" placeholder="ISS"/></td>
            <td style="width:20%;"><label for="keyword5">KeyWord 5: </label></br>
        <input class="gate" type="text" id="keyword5" name="keyword5" style="width: 100px;" placeholder="space junk"/></td>
        </tr>
        <caption>Table below is for entering a new blog post.</caption>
        <tr> </tr>
    </table>
        <input type="submit" name="new_blog_entry" class="btn" value="Enter Blog Info">
    </form>
</div>

<h2 class="center">Payment Status</br>House Data vs. Blockchain</h2>

<div class="row">
<p class=:center">Query current payment status internally and on the blockchain.</p>
    
  <form action="dataControl.php" method="POST">
    <table>
        <tr>
            <th colspan="2"></th><th></th>
        </tr>
        <!-- Input Payment ID  -->
        <tr>
            <td colspan="2"><label for="payment_id">Enter Payment ID: </label></br>
        <input class="gate" type="text" id="payment_id" name="payment_id" placeholder="9876543201"/></td></td><td></td>
        </tr>
        <tr>
            <td style="height:100px; width: 2rem">MBC Status</td><td>NOWPayments Status</td>
        </tr>
        <tr>
            <td style="height: 1em;width:300px; text-align: center;"><?php echo $MBCPayments_status; ?></td style="height: 1em;width:300px; text-align: center;"><td><?php echo $NOWPayments_status; ?></td>
        </tr>
        
        <tr> </tr>
    </table>
    <input type="submit" name="payment_verification" class="btn" value="Enter Payment ID">
  </form>
</div>

    </body>

    </html>

Try adding this at the beginning (and end) of your file:

header("Content-Disposition: inline");

I just tried that, but the behavior is the same. I’m a bit baffled why I never had to add anything in the past. Inline (display the page) is suppose to be the default, right?
Bye the ‘end’ of the file, you mean the end of the PHP section at the top or do I add another PHP section below the HTML?
I’m trying to see what you see. I go to the panel, hit ‘network’ – ALL and tried ‘header’ in the filter. I get the download panel for dataControl.php and do not see any headers, then my index.html page is loaded instead.

Do you have anything on Cloudflare that could cause this? or in .htaccess ?

everything starting with “d” in that URL goes to download !

etc.

not just https://michaelsbookcorner.com/dataControl.php

2 Likes

Not sure what to check on in Cloudflare. No special firewall rules that should interfere. What should I look for in Cloudflare?

I will try changing the name of the file and matching internal references, but really, I should not have to do that normally, I’m assuming.

Here is what I have in .htaccess.


php_value display_errors Off
php_value mbstring.http_input auto
php_value date.timezone America/Los_Angeles
RewriteEngine on
RewriteRule ^d/([0-9a-zA-Z_-]+)$ downloadFiles.php?u=$1 [NC,L]
RewriteRule ^d  downloadFiles.php [NC,L]

ErrorDocument 404 /404.html

# Deny access to .htaccess
<Files .htaccess>
Order allow,deny
Deny from all
</Files>

# Disable directory browsing 
Options -Indexes

# Hide the contents of directories
IndexIgnore *

# Deny access to files with extensions .ini, .psd, .log, .sh
<FilesMatch "\.(ini|psd|log|sh)$">
Order allow,deny
Deny from all

</FilesMatch>

# Deny access to filenames starting with dot(.)
<FilesMatch "^\.">
Order allow,deny
Deny from all
</FilesMatch>
1 Like

This is your problem. Try commenting this line.

3 Likes

emphasis on this ^d (Called an anchor, matches the beginning of the string)

1 Like

That appears to have been the culprit!
I’m not really up on .htaccess controls, obviously. I was attempting to copy some protection statements in for my files without realy understanding what they all mean. Another topic for my research!

First I changed the file name from dataControl.php to controlData.php and that worked. Then I took out those statements in the .htaccess file, cleared my cache, and the original file, dataControl.php worked without any changes.

Thank you guys for all of your wonderful help!

Michael J. Scharen

5 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.