@esartium

Почему не работает POST-запрос от React(+Redux) к PHP?

Не получается сделать POST-запрос от React к PHP.
Была попытка сделать через fetch и через axios, и результат обеих - ошибка:

<b>Warning</b>:  Undefined array key "perem" in <b>/Applications/MAMP/htdocs/PHP_integr/functions.php</b> on line <b>49</b>


Код PHP:

Файл с API-методами - functions.php (вставлю тут только тот, который нужен для POST-запроса):

function addTableNote($conn, $data) {
    $perem = $data['perem'];
    mysqli_query($conn, "INSERT INTO `table` (`perem`) VALUES ('$perem')");

    $res = [
        "status" => true,
        "note_id" => mysqli_insert_id($conn)
    ];
    http_response_code(201);

    echo json_encode($res);
}


Файл, в котором этот метод вызывается - index.php:

<?php
require "functions.php";

header('Access-Control-Allow-Origin: http://localhost:3000');
header('Access-Control-Allow-Headers: *');
header('Content-type: application/json');

$conn = mysqli_connect("localhost", "root", "root", "integr");
if($conn->connect_error) {
    die("Ошибка соединения: " . $conn->connect_error);
}

$type = $_GET['q'];
$params = explode('/', $type);
$typeMain = $params[0];
if (count($params) > 1) {
$typeSecond = $params[1];
}

$method = $_SERVER['REQUEST_METHOD'];

switch ($method) {
    case 'GET':
        if ($typeMain === 'notes') {
            if (isset($typeSecond)) {
                getOneById($conn, $typeSecond);
            } else {
                getTableData($conn);
            }
        }
        break;
    case 'POST':
        if ($typeMain === 'notes') {
            addTableNote($conn, $_POST);
        }
        break;
    case 'PATCH':
        if ($typeMain === 'notes') {
            if (isset($typeSecond)) {

                // получение данных для PATCH:
                $data = file_get_contents('php://input');
                $data = json_decode($data, true);
                print_r($data['perem']);
                updateTableNote($conn, $data, $typeSecond);
            }
        }
        break;
    case 'DELETE':
        if ($typeMain === 'notes') {
            if (isset($typeSecond)) {
                deleteTableNote($conn, $typeSecond);
            }
        }
}


Код на React/Redux:

Через fetch:

Файл, содержащий функцию для самого запроса (скорее всего, тут должен быть dispatch, вот только где?):

export const addNote = (perem) => {
   
      fetch("http://localhost:8888/PHP_integr/notes", {
      method: 'POST',
      header: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        perem: perem
      })
    }).then(response => response.json())
    .then(response => console.log(response))
    
}


Вот так вызываю эту функцию:

const perem = useSelector(state => state.perem.perem)

<button type="button" onClick={() => addNote(perem)}> send note to the server </button>


Состояние perem точно не пустое, с этим все нормально.

Через axios:

axiosReducer.js:

const defaultState = {
  loading: false,
  notes: [],
  error: null
}

const ADD_NOTE_STARTED = "ADD_NOTE_STARTED"
const ADD_NOTE_SUCCESS = "ADD_NOTE_SUCCESS"
const ADD_NOTE_FAILURE = "ADD_NOTE_FAILURE"

export default function axiosReducer(state = defaultState, action) {
    switch(action.type) {
        case ADD_NOTE_STARTED:
      return {
        ...state,
        loading: true
      };
    case ADD_NOTE_SUCCESS:
      return {
        ...state,
        loading: false,
        error: null,
        notes: [...state.notes, action.payload]
      };
    case ADD_NOTE_FAILURE:
      return {
        ...state,
        loading: false,
        error: action.payload.error
      };
    default:
      return state;
    }
}

export const addNoteStarted = () => ({type: ADD_NOTE_STARTED})
export const addNoteSuccess = (note) => ({
    type: ADD_NOTE_SUCCESS,
    payload: {
        ...note
    }
})
export const addNoteFailure = (error) => ({
    type: ADD_NOTE_FAILURE,
    payload: {
        error
    }
})


Файл функции с запросом:

import axios from 'axios';
import { addNoteStarted, addNoteSuccess, addNoteFailure } from '../store/axiosReducer';

export const addNoteAxios = (perem) => {
    return dispatch => {
        dispatch(addNoteStarted())

        axios
      .post(`http://localhost:8888/PHP_integr/notes`, {
        perem
      })
      .then(res => {
        dispatch(addNoteSuccess(res.data));
      })
      .catch(err => {
        dispatch(addNoteFailure(err.message));
      });
    }
}


Вызываю её так:

const perem = useSelector(state => state.perem.perem)

          <br /><button type="button" onClick={() => dispatch(addNoteAxios(perem))}> add note axios </button>


В store/index.js rootReducer такой:

const rootReducer = combineReducers({
    perem: peremReducer,
    axios: axiosReducer
})
  • Вопрос задан
  • 147 просмотров
Решения вопроса 1
pickHabr
@pickHabr
Костыльных дел мастер
Undefined array key "perem" on line 49


$perem = $data['perem'];
- вот тут у тебя нет в массиве data (а это переданный массив POST) нужной переменной.

Пропиши
var_dump($data);
exit;

перед
$perem = $data['perem'];
например и посмотри что там в принципе лежит (если будешь дергать из браузера то надо смотреть в разделе network response)

UPD
Не обратил внимание сразу, с фронта уходит

Content-type: application/json


PHP не умеет обрабатывать такое через суперглобальную переменную $_POST
Поменяй либо получение данных с

addTableNote($conn, $_POST);

на
$data = json_decode(file_get_contents('php://input'), true);
addTableNote($conn, $data);


либо с фронта отправляй как FormData
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы