使用 public 目录外的 php 文件?我可以访问该文件但收到错误
Work with php file outside public directory? I can access the file but receive error
我开始感到沮丧,无法使用 public 文件夹外的 php 文件。我正在使用 fineuploader 和这个 php 迷你框架 https://github.com/panique/mini。我有以下文件结构,其中“public”是我的 public 目录。
application
--controller
----album.php
--libs
--model
public
--css
--img
--js
----application.js
我想使用 application.js 中 javascript 的 php 文件。如果我这样做并将 s3demo 放在 public/js 文件夹中,一切正常。
signature: {
endpoint: url + "/js/application/s3demo.php"
},
但我想在 application/libs 文件夹中放置 s3demo.php 而不是 /js/application
我已经通过以下代码使用我的控制器
Javascript 指向我的控制器而不是 php-文件
signature: {
endpoint: url + "/album/s3upload"
},
我的控制器看起来像这样
public function s3upload() {
require APP . '/libs/s3demo.php';
}
当我 运行 代码时,我在浏览器 NET 选项卡中收到以下错误消息 -> Response
Notice: Undefined index: _method in
/home/connecti/public_html/application/libs/s3demo.php on line 78
Warning: Cannot modify header information - headers already sent by
(output started at
/home/connecti/public_html/application/libs/s3demo.php:77) in
/home/connecti/public_html/application/libs/s3demo.php on line 103
Notice: Undefined index: headers in
/home/connecti/public_html/application/libs/s3demo.php on line 109
{"invalid":true}
我的控制器可以访问我的 s3admin.php(我在 s3admin.php 中有一个名为“_method”的索引)。但感觉我的 php 文件不知道我的 javascript 什么的。我应该怎么做才能从我的 libs 文件夹中 运行t s3demo.php?如果 public 文件夹中有 s3demo 并且文件上传工作正常,我不会收到任何错误。如果我的 libs 文件夹中有 s3demo.php,我会收到上述错误并且我的文件未上传。
所有javascript代码
<script>
$(document).ready(function () {
$('#fineuploader-s3').fineUploaderS3({
request: {
// REQUIRED: We are using a custom domain
// for our S3 bucket, in this case. You can
// use any valid URL that points to your bucket.
endpoint: "upload.fineuploader.com",
// REQUIRED: The AWS public key for the client-side user
// we provisioned.
accessKey: "AKIAJB6BSMFWTAXC5M2Q"
},
template: "simple-previews-template",
// REQUIRED: Path to our local server where requests
// can be signed.
signature: {
endpoint: "/s3demo.php"
},
// OPTIONAL: An endopint for Fine Uploader to POST to
// after the file has been successfully uploaded.
// Server-side, we can declare this upload a failure
// if something is wrong with the file.
uploadSuccess: {
endpoint: "/s3demo.php?success"
},
// USUALLY REQUIRED: Blank file on the same domain
// as this page, for IE9 and older support.
iframeSupport: {
localBlankPagePath: "/server/success.html"
},
// optional feature
chunking: {
enabled: true
},
// optional feature
resume: {
enabled: true
},
// optional feature
deleteFile: {
enabled: true,
method: "POST",
endpoint: "/s3demo.php"
},
// optional feature
validation: {
itemLimit: 5,
sizeLimit: 15000000
},
thumbnails: {
placeholders: {
notAvailablePath: "assets/not_available-generic.png",
waitingPath: "assets/waiting-generic.png"
}
}
})
// Enable the "view" link in the UI that allows the file to be downloaded/viewed
.on('complete', function(event, id, name, response) {
var $fileEl = $(this).fineUploaderS3("getItemByFileId", id),
$viewBtn = $fileEl.find(".view-btn");
if (response.success) {
$viewBtn.show();
$viewBtn.attr("href", response.tempLink);
}
});
});
</script>
s3demo.php
中的所有php代码
<?php
/**
* PHP Server-Side Example for Fine Uploader S3.
* Maintained by Widen Enterprises.
*
*
* This example:
* - handles non-CORS environment
* - handles size validation and no size validation
* - handles delete file requests for both DELETE and POST methods
* - Performs basic inspections on the policy documents and REST headers before signing them
* - Ensures again the file size does not exceed the max (after file is in S3)
* - signs policy documents (simple uploads) and REST requests
* (chunked/multipart uploads)
*
* Requirements:
* - PHP 5.3 or newer
* - Amazon PHP SDK (only if utilizing the AWS SDK for deleting files or otherwise examining them)
*
* If you need to install the AWS SDK, see http://docs.aws.amazon.com/aws-sdk-php-2/guide/latest/installation.html.
*/
// You can remove these two lines if you are not using Fine Uploader's
// delete file feature
require 'aws/aws-autoloader.php';
use Aws\S3\S3Client;
// These assume you have the associated AWS keys stored in
// the associated system environment variables
$clientPrivateKey = $_SERVER['AWS_SECRET_KEY'];
// These two keys are only needed if the delete file feature is enabled
// or if you are, for example, confirming the file size in a successEndpoint
// handler via S3's SDK, as we are doing in this example.
$serverPublicKey = $_SERVER['PARAM1'];
$serverPrivateKey = $_SERVER['PARAM2'];
// The following variables are used when validating the policy document
// sent by the uploader.
$expectedBucketName = "upload.fineuploader.com";
// $expectedMaxSize is the value you set the sizeLimit property of the
// validation option. We assume it is `null` here. If you are performing
// validation, then change this to match the integer value you specified
// otherwise your policy document will be invalid.
// http://docs.fineuploader.com/branch/develop/api/options.html#validation-option
$expectedMaxSize = null;
$method = getRequestMethod();
// This second conditional will only ever evaluate to true if
// the delete file feature is enabled
if ($method == "DELETE") {
deleteObject();
}
// This is all you really need if not using the delete file feature
// and not working in a CORS environment
else if ($method == 'POST') {
// Assumes the successEndpoint has a parameter of "success" associated with it,
// to allow the server to differentiate between a successEndpoint request
// and other POST requests (all requests are sent to the same endpoint in this example).
// This condition is not needed if you don't require a callback on upload success.
if (isset($_REQUEST["success"])) {
verifyFileInS3();
}
else {
signRequest();
}
}
// This will retrieve the "intended" request method. Normally, this is the
// actual method of the request. Sometimes, though, the intended request method
// must be hidden in the parameters of the request. For example, when attempting to
// send a DELETE request in a cross-origin environment in IE9 or older, it is not
// possible to send a DELETE request. So, we send a POST with the intended method,
// DELETE, in a "_method" parameter.
function getRequestMethod() {
if ($_POST['_method'] != null) {
return $_POST['_method'];
}
return $_SERVER['REQUEST_METHOD'];
}
function getS3Client() {
global $serverPublicKey, $serverPrivateKey;
return S3Client::factory(array(
'key' => $serverPublicKey,
'secret' => $serverPrivateKey
));
}
// Only needed if the delete file feature is enabled
function deleteObject() {
getS3Client()->deleteObject(array(
'Bucket' => $_POST['bucket'],
'Key' => $_POST['key']
));
}
function signRequest() {
header('Content-Type: application/json');
$responseBody = file_get_contents('php://input');
$contentAsObject = json_decode($responseBody, true);
$jsonContent = json_encode($contentAsObject);
$headersStr = $contentAsObject["headers"];
if ($headersStr) {
signRestRequest($headersStr);
}
else {
signPolicy($jsonContent);
}
}
function signRestRequest($headersStr) {
if (isValidRestRequest($headersStr)) {
$response = array('signature' => sign($headersStr));
echo json_encode($response);
}
else {
echo json_encode(array("invalid" => true));
}
}
function isValidRestRequest($headersStr) {
global $expectedBucketName;
$pattern = "/\/$expectedBucketName\/.+$/";
preg_match($pattern, $headersStr, $matches);
return count($matches) > 0;
}
function signPolicy($policyStr) {
$policyObj = json_decode($policyStr, true);
if (isPolicyValid($policyObj)) {
$encodedPolicy = base64_encode($policyStr);
$response = array('policy' => $encodedPolicy, 'signature' => sign($encodedPolicy));
echo json_encode($response);
}
else {
echo json_encode(array("invalid" => true));
}
}
function isPolicyValid($policy) {
global $expectedMaxSize, $expectedBucketName;
$conditions = $policy["conditions"];
$bucket = null;
$parsedMaxSize = null;
for ($i = 0; $i < count($conditions); ++$i) {
$condition = $conditions[$i];
if (isset($condition["bucket"])) {
$bucket = $condition["bucket"];
}
else if (isset($condition[0]) && $condition[0] == "content-length-range") {
$parsedMaxSize = $condition[2];
}
}
return $bucket == $expectedBucketName && $parsedMaxSize == (string)$expectedMaxSize;
}
function sign($stringToSign) {
global $clientPrivateKey;
return base64_encode(hash_hmac(
'sha1',
$stringToSign,
$clientPrivateKey,
true
));
}
// This is not needed if you don't require a callback on upload success.
function verifyFileInS3() {
global $expectedMaxSize;
$bucket = $_POST["bucket"];
$key = $_POST["key"];
// If utilizing CORS, we return a 200 response with the error message in the body
// to ensure Fine Uploader can parse the error message in IE9 and IE8,
// since XDomainRequest is used on those browsers for CORS requests. XDomainRequest
// does not allow access to the response body for non-success responses.
if (getObjectSize($bucket, $key) > $expectedMaxSize) {
// You can safely uncomment this next line if you are not depending on CORS
header("HTTP/1.0 500 Internal Server Error");
deleteObject();
echo json_encode(array("error" => "File is too big!"));
}
else {
echo json_encode(array("tempLink" => getTempLink($bucket, $key)));
}
}
// Provide a time-bombed public link to the file.
function getTempLink($bucket, $key) {
$client = getS3Client();
$url = "{$bucket}/{$key}";
$request = $client->get($url);
return $client->createPresignedUrl($request, '+15 minutes');
}
function getObjectSize($bucket, $key) {
$objInfo = getS3Client()->headObject(array(
'Bucket' => $bucket,
'Key' => $key
));
return $objInfo['ContentLength'];
}
?>
您收到一条通知消息,然后 headers 无法发送。在脚本开头使用 error_reporting(E_ALL ^ E_NOTICE) 禁用通知消息;
我开始感到沮丧,无法使用 public 文件夹外的 php 文件。我正在使用 fineuploader 和这个 php 迷你框架 https://github.com/panique/mini。我有以下文件结构,其中“public”是我的 public 目录。
application
--controller
----album.php
--libs
--model
public
--css
--img
--js
----application.js
我想使用 application.js 中 javascript 的 php 文件。如果我这样做并将 s3demo 放在 public/js 文件夹中,一切正常。
signature: {
endpoint: url + "/js/application/s3demo.php"
},
但我想在 application/libs 文件夹中放置 s3demo.php 而不是 /js/application
我已经通过以下代码使用我的控制器
Javascript 指向我的控制器而不是 php-文件
signature: {
endpoint: url + "/album/s3upload"
},
我的控制器看起来像这样
public function s3upload() {
require APP . '/libs/s3demo.php';
}
当我 运行 代码时,我在浏览器 NET 选项卡中收到以下错误消息 -> Response
Notice: Undefined index: _method in /home/connecti/public_html/application/libs/s3demo.php on line 78
Warning: Cannot modify header information - headers already sent by (output started at /home/connecti/public_html/application/libs/s3demo.php:77) in /home/connecti/public_html/application/libs/s3demo.php on line 103
Notice: Undefined index: headers in /home/connecti/public_html/application/libs/s3demo.php on line 109 {"invalid":true}
我的控制器可以访问我的 s3admin.php(我在 s3admin.php 中有一个名为“_method”的索引)。但感觉我的 php 文件不知道我的 javascript 什么的。我应该怎么做才能从我的 libs 文件夹中 运行t s3demo.php?如果 public 文件夹中有 s3demo 并且文件上传工作正常,我不会收到任何错误。如果我的 libs 文件夹中有 s3demo.php,我会收到上述错误并且我的文件未上传。
所有javascript代码
<script>
$(document).ready(function () {
$('#fineuploader-s3').fineUploaderS3({
request: {
// REQUIRED: We are using a custom domain
// for our S3 bucket, in this case. You can
// use any valid URL that points to your bucket.
endpoint: "upload.fineuploader.com",
// REQUIRED: The AWS public key for the client-side user
// we provisioned.
accessKey: "AKIAJB6BSMFWTAXC5M2Q"
},
template: "simple-previews-template",
// REQUIRED: Path to our local server where requests
// can be signed.
signature: {
endpoint: "/s3demo.php"
},
// OPTIONAL: An endopint for Fine Uploader to POST to
// after the file has been successfully uploaded.
// Server-side, we can declare this upload a failure
// if something is wrong with the file.
uploadSuccess: {
endpoint: "/s3demo.php?success"
},
// USUALLY REQUIRED: Blank file on the same domain
// as this page, for IE9 and older support.
iframeSupport: {
localBlankPagePath: "/server/success.html"
},
// optional feature
chunking: {
enabled: true
},
// optional feature
resume: {
enabled: true
},
// optional feature
deleteFile: {
enabled: true,
method: "POST",
endpoint: "/s3demo.php"
},
// optional feature
validation: {
itemLimit: 5,
sizeLimit: 15000000
},
thumbnails: {
placeholders: {
notAvailablePath: "assets/not_available-generic.png",
waitingPath: "assets/waiting-generic.png"
}
}
})
// Enable the "view" link in the UI that allows the file to be downloaded/viewed
.on('complete', function(event, id, name, response) {
var $fileEl = $(this).fineUploaderS3("getItemByFileId", id),
$viewBtn = $fileEl.find(".view-btn");
if (response.success) {
$viewBtn.show();
$viewBtn.attr("href", response.tempLink);
}
});
});
</script>
s3demo.php
中的所有php代码<?php
/**
* PHP Server-Side Example for Fine Uploader S3.
* Maintained by Widen Enterprises.
*
*
* This example:
* - handles non-CORS environment
* - handles size validation and no size validation
* - handles delete file requests for both DELETE and POST methods
* - Performs basic inspections on the policy documents and REST headers before signing them
* - Ensures again the file size does not exceed the max (after file is in S3)
* - signs policy documents (simple uploads) and REST requests
* (chunked/multipart uploads)
*
* Requirements:
* - PHP 5.3 or newer
* - Amazon PHP SDK (only if utilizing the AWS SDK for deleting files or otherwise examining them)
*
* If you need to install the AWS SDK, see http://docs.aws.amazon.com/aws-sdk-php-2/guide/latest/installation.html.
*/
// You can remove these two lines if you are not using Fine Uploader's
// delete file feature
require 'aws/aws-autoloader.php';
use Aws\S3\S3Client;
// These assume you have the associated AWS keys stored in
// the associated system environment variables
$clientPrivateKey = $_SERVER['AWS_SECRET_KEY'];
// These two keys are only needed if the delete file feature is enabled
// or if you are, for example, confirming the file size in a successEndpoint
// handler via S3's SDK, as we are doing in this example.
$serverPublicKey = $_SERVER['PARAM1'];
$serverPrivateKey = $_SERVER['PARAM2'];
// The following variables are used when validating the policy document
// sent by the uploader.
$expectedBucketName = "upload.fineuploader.com";
// $expectedMaxSize is the value you set the sizeLimit property of the
// validation option. We assume it is `null` here. If you are performing
// validation, then change this to match the integer value you specified
// otherwise your policy document will be invalid.
// http://docs.fineuploader.com/branch/develop/api/options.html#validation-option
$expectedMaxSize = null;
$method = getRequestMethod();
// This second conditional will only ever evaluate to true if
// the delete file feature is enabled
if ($method == "DELETE") {
deleteObject();
}
// This is all you really need if not using the delete file feature
// and not working in a CORS environment
else if ($method == 'POST') {
// Assumes the successEndpoint has a parameter of "success" associated with it,
// to allow the server to differentiate between a successEndpoint request
// and other POST requests (all requests are sent to the same endpoint in this example).
// This condition is not needed if you don't require a callback on upload success.
if (isset($_REQUEST["success"])) {
verifyFileInS3();
}
else {
signRequest();
}
}
// This will retrieve the "intended" request method. Normally, this is the
// actual method of the request. Sometimes, though, the intended request method
// must be hidden in the parameters of the request. For example, when attempting to
// send a DELETE request in a cross-origin environment in IE9 or older, it is not
// possible to send a DELETE request. So, we send a POST with the intended method,
// DELETE, in a "_method" parameter.
function getRequestMethod() {
if ($_POST['_method'] != null) {
return $_POST['_method'];
}
return $_SERVER['REQUEST_METHOD'];
}
function getS3Client() {
global $serverPublicKey, $serverPrivateKey;
return S3Client::factory(array(
'key' => $serverPublicKey,
'secret' => $serverPrivateKey
));
}
// Only needed if the delete file feature is enabled
function deleteObject() {
getS3Client()->deleteObject(array(
'Bucket' => $_POST['bucket'],
'Key' => $_POST['key']
));
}
function signRequest() {
header('Content-Type: application/json');
$responseBody = file_get_contents('php://input');
$contentAsObject = json_decode($responseBody, true);
$jsonContent = json_encode($contentAsObject);
$headersStr = $contentAsObject["headers"];
if ($headersStr) {
signRestRequest($headersStr);
}
else {
signPolicy($jsonContent);
}
}
function signRestRequest($headersStr) {
if (isValidRestRequest($headersStr)) {
$response = array('signature' => sign($headersStr));
echo json_encode($response);
}
else {
echo json_encode(array("invalid" => true));
}
}
function isValidRestRequest($headersStr) {
global $expectedBucketName;
$pattern = "/\/$expectedBucketName\/.+$/";
preg_match($pattern, $headersStr, $matches);
return count($matches) > 0;
}
function signPolicy($policyStr) {
$policyObj = json_decode($policyStr, true);
if (isPolicyValid($policyObj)) {
$encodedPolicy = base64_encode($policyStr);
$response = array('policy' => $encodedPolicy, 'signature' => sign($encodedPolicy));
echo json_encode($response);
}
else {
echo json_encode(array("invalid" => true));
}
}
function isPolicyValid($policy) {
global $expectedMaxSize, $expectedBucketName;
$conditions = $policy["conditions"];
$bucket = null;
$parsedMaxSize = null;
for ($i = 0; $i < count($conditions); ++$i) {
$condition = $conditions[$i];
if (isset($condition["bucket"])) {
$bucket = $condition["bucket"];
}
else if (isset($condition[0]) && $condition[0] == "content-length-range") {
$parsedMaxSize = $condition[2];
}
}
return $bucket == $expectedBucketName && $parsedMaxSize == (string)$expectedMaxSize;
}
function sign($stringToSign) {
global $clientPrivateKey;
return base64_encode(hash_hmac(
'sha1',
$stringToSign,
$clientPrivateKey,
true
));
}
// This is not needed if you don't require a callback on upload success.
function verifyFileInS3() {
global $expectedMaxSize;
$bucket = $_POST["bucket"];
$key = $_POST["key"];
// If utilizing CORS, we return a 200 response with the error message in the body
// to ensure Fine Uploader can parse the error message in IE9 and IE8,
// since XDomainRequest is used on those browsers for CORS requests. XDomainRequest
// does not allow access to the response body for non-success responses.
if (getObjectSize($bucket, $key) > $expectedMaxSize) {
// You can safely uncomment this next line if you are not depending on CORS
header("HTTP/1.0 500 Internal Server Error");
deleteObject();
echo json_encode(array("error" => "File is too big!"));
}
else {
echo json_encode(array("tempLink" => getTempLink($bucket, $key)));
}
}
// Provide a time-bombed public link to the file.
function getTempLink($bucket, $key) {
$client = getS3Client();
$url = "{$bucket}/{$key}";
$request = $client->get($url);
return $client->createPresignedUrl($request, '+15 minutes');
}
function getObjectSize($bucket, $key) {
$objInfo = getS3Client()->headObject(array(
'Bucket' => $bucket,
'Key' => $key
));
return $objInfo['ContentLength'];
}
?>
您收到一条通知消息,然后 headers 无法发送。在脚本开头使用 error_reporting(E_ALL ^ E_NOTICE) 禁用通知消息;