澄清一下:.php 文件是我教授的,不会被更改。 问题出现是因为第 186 行的
$VALORES
未初始化,我已经将它发给了我的教授。
这是代码:
<form onsubmit="crearPublicacion(event);">
<div>
<label>Título:</label>
<input type="text" name="titulo">
</div>
<div>
<label>Texto:</label>
<textarea name="texto"></textarea>
</div>
<div>
<label>Zona:</label>
<input type="text" name="zona">
</div>
<div id="fotos">
<div>
<input type="file" name="fotos[]" accept="image/*">
<textarea name="descripciones[]"></textarea>
</div>
<div>
<input type="file" name="fotos[]" accept="image/*">
<textarea name="descripciones[]"></textarea>
</div>
<div>
<input type="file" name="fotos[]" accept="image/*">
<textarea name="descripciones[]"></textarea>
</div>
<div>
<input type="submit">
</div>
</div>
</form>
function crearPublicacion(evt) {
evt.preventDefault(); // Cancela el comportamiento por defecto
let xhr = new XMLHttpRequest(),
url = 'api/publicaciones',
fd = new FormData(evt.currentTarget),
usu = JSON.parse(sessionStorage['_datos_']),
auth = `${usu.LOGIN}:${usu.TOKEN}`;
xhr.open('POST', url, true);
xhr.responseType = 'json';
xhr.onload = (evt) => {
let r = xhr.response;
console.log(r);
};
xhr.setRequestHeader('Authorization', auth);
xhr.send(fd);
}
<?php
require_once('../inc/config.php'); // Constantes, etc ...
require_once('../inc/database.php');
$db = new Database();
$dbCon = $db->getConnection();
$dbCon->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
header("Access-Control-Allow-Orgin: *");
header("Access-Control-Allow-Methods: POST");
header("Content-Type: application/json; charset=UTF-8");
$RECURSO = explode("/", substr($_GET['prm'],1));
$headers = apache_request_headers();
if(isset($headers['Authorization']))
$AUTORIZACION = $headers['Authorization'];
elseif (isset($headers['authorization']))
$AUTORIZACION = $headers['authorization'];
if(!isset($AUTORIZACION))
{ // Acceso no autorizado
$RESPONSE_CODE = 403;
$R['RESULTADO'] = 'ERROR';
$R['CODIGO'] = $RESPONSE_CODE;
$R['DESCRIPCION'] = 'Falta autorización';
}
else
{
$R = []; // Almacenará el resultado.
$RESPONSE_CODE = 200; // código de respuesta por defecto: 200 - OK
$PARAMS = $_POST;
list($login,$token) = explode(':', $AUTORIZACION);
if( !$db->comprobarSesion($login,$token) )
{
$RESPONSE_CODE = 401;
$R['RESULTADO'] = 'ERROR';
$R['CODIGO'] = $RESPONSE_CODE;
$R['DESCRIPCION'] = 'Error de autenticación.';
}
else
{
$ID = array_shift($RECURSO);
try{
$dbCon->beginTransaction();
if(!is_numeric($ID)) // NUEVO REGISTRO
{ // Si no es numérico $ID es porque se está creando un nuevo registro
$titulo = $PARAMS['titulo'];
$texto = nl2br($PARAMS['texto'],false);
$zona = $PARAMS['zona'];
$descripciones = $PARAMS['descripciones'];
$mysql = 'select * from zona where nombre=:ZONA';
$RESPUESTA = $db->select($mysql, [':ZONA'=>$zona]);
if( $RESPUESTA['CORRECTO'] ) // execute query OK
{
if(count($RESPUESTA['RESULT']) > 0)
{ // encontrado
$idZona = $RESPUESTA['RESULT'][0]['id'];
}
else
{ // No existe la zona. Hay que crearla.
$mysql = 'insert into zona(nombre) values(:NOMBRE)';
if( $db->executeStatement($mysql, [':NOMBRE'=>$zona]) )
{
$mysql = 'select max(id) as idZona from zona';
$RESPUESTA = $db->select($mysql, $VALORES);
if( $RESPUESTA['CORRECTO'] ) // execute query OK
{
if(count($RESPUESTA['RESULT']) > 0)
{ // encontrado
$idZona = $RESPUESTA['RESULT'][0]['idZona'];
}
}
}
}
}
$mysql = 'insert into publicacion(titulo,texto,idZona,autor) ';
$mysql .= 'values(:TITULO,:TEXTO,:ID_ZONA,:AUTOR)';
$VALORES = [];
$VALORES[':TITULO'] = $titulo;
$VALORES[':TEXTO'] = $texto;
$VALORES[':ID_ZONA'] = $idZona;
$VALORES[':AUTOR'] = $login;
if( $db->executeStatement($mysql, $VALORES) )
{
$mysql = "select MAX(id) as id_pub from publicacion";
$RESPUESTA = $db->select($mysql);
if($RESPUESTA['CORRECTO'])
{
$ID = $RESPUESTA['RESULT'][0]['id_pub'];
$RESPONSE_CODE = 201;
$R['RESULTADO'] = 'OK';
$R['CODIGO'] = $RESPONSE_CODE;
$R['DESCRIPCION'] = 'Registro creado correctamente';
$R['ID'] = $ID;
$R['TITULO'] = $titulo;
$R['FOTOS'] = $fotos;
}
else
$ID = -1;
}
else
{
$RESPONSE_CODE = 500; // INTERNAL SERVER ERROR
$R['RESULTADO'] = 'ERROR';
$R['CODIGO'] = $RESPONSE_CODE;
$R['DESCRIPCION'] = 'Error indefinido al crear el nuevo registro';
}
}
$dbCon->commit();
}catch(Exception $e){
echo $e;
$dbCon->rollBack();
}
}
}
$dbCon = null;
http_response_code($RESPONSE_CODE);
echo json_encode($R);
?>
<?php
class Database{
private $HOST = "127.0.0.1";
private $DB_DATABASE_NAME = "websocial";
private $DB_USERNAME = "pcw";
private $DB_PASSWORD = "pcw";
public $conn;
public function __construct() {...}
public function select($query = "" , $params = [])
{
$result = false;
$RESPUESTA = [];
try {
$stmt = $this->conn->prepare( $query );
if($stmt === false) {
throw New Exception("Unable to do prepared statement: " . $query);
}
$stmt->execute($params);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$RESPUESTA['CORRECTO'] = true;
} catch(Exception $e) {
// throw New Exception( $e->getMessage() );
$RESPUESTA['CORRECTO'] = false;
$RESPUESTA['ERROR'] = $e->getMessage();
}
$RESPUESTA['RESULT'] = $result;
return $RESPUESTA;
}
public function executeStatement($query = "", $params = [])
{
$retVal = false;
try {
$stmt = $this->conn->prepare( $query );
if($stmt === false) {
throw New Exception("Unable to do prepared statement: " . $query);
}
if( $params )
$retVal = $stmt->execute($params);
else
$retVal = $stmt->execute();
} catch(Exception $e) {
throw New Exception( $e->getMessage() );
}
return $retVal;
}
}
?>
如您所见,在第 186 行调用
$VALORES
时,select
(publicacion.php) 尚未初始化(这是每当我尝试在 Postman 中执行 POST 时它给我的警告)。解决方案就像完全删除 $VALORES 一样简单。
给大家一个思路,这是预期的结果:
{
"RESULTADO": "OK",
"CODIGO": 201,
"DESCRIPCION": "Registro creado correctamente",
"ID": 109,
"TITULO": "",
"FOTOS": []
}
但是只有当“zona”的值在数据库中不存在时才会发生这种情况(如果它已经存在,那么响应总是上面的):
警告:第 186 行 C:\xampp\htdocs\pcw\practica2 pi\post\publicaciones.php 中的未定义变量 $VALORES
{
"RESULTADO": "OK",
"CODIGO": 201,
"DESCRIPCION": "Registro creado correctamente",
"ID": 109,
"TITULO": "",
"FOTOS": []
}
null
正如我之前所说,我已经解决了这个问题,但我的问题是为什么会发生以及具体发生在哪里。
什么时候我的
xhr.response
设置为null
?我能找到的唯一解释是,即使代码运行正常(即没有陷入 catch 和 throw 语句并且根本没有退出),发出警告也会以某种方式使响应无效。
https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/responseType#value:
当将 responseType 设置为特定值时,作者应确保服务器实际发送与该格式兼容的响应。如果服务器返回的数据与设置的 responseType 不兼容,则 response 的值为 null。
使用
xhr.responseType = 'json';
你告诉浏览器,响应将是 JSON,并且它应该自动为你解析它。
但是“随机 PHP 警告消息后跟一些 JSON”不是有效的 JSON。因此它将您的响应值设置为 null。