从angular 2发布JSON到php

lyfkaqu1  于 10个月前  发布在  PHP
关注(0)|答案(4)|浏览(78)

我试着将angular 2的数据发布到php:

let headers = new Headers();
headers.append('Content-Type', 'application/json');
var order = {'order': this.orders};

this.http.post('http://myserver/processorder.php', JSON.stringify(order), {
    headers: headers
}).subscribe(res => {
    console.log('post result %o', res);
});

字符串
在Angular 2中,只能将字符串作为数据发布,而不能将Json发布?这对我来说是可以的,但我很难在PHP上获得发布的数据。我试过$obj = $_POST['order'];

8fq7wneg

8fq7wneg1#

Marc B是正确的,但是发生的是$_POST数组将包含一个空值,其中一个键设置为您正在传递的JSON字符串...

Array
(
    [{"order":"foobar"}] => 
)

字符串
您可以通过使用...获取密钥来“抓住”它(尽管这是错误的方法)。

key($_POST)


例如:

$obj = json_decode(key($_POST));
echo $obj->order;

但是你可以做的是将数据作为值密钥对发送:

let headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
let order = 'order=foobar';

this.http.post('http://myserver/processorder.php', order, {
    headers: headers
}).subscribe(res => {
    console.log('post result %o', res);
});


然后在PHP中,你可以使用以下命令获取数据:

$_POST['order']


需要注意的几点:

  • 将头Content-Type更改为application/x-www-form-urlencoded(更多是为了我自己的测试,因为这不做任何预检请求)
  • 注意order是一个键值对字符串,而不是JSON
  • 请注意,this.http.post中的order将按原样传递,而不使用JSON.stringify
mm9b1k5b

mm9b1k5b2#

我不知道这是不是不好的做法,但对我来说,这似乎是正确的,虽然它让我有点困扰

const headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');

const obj = { nome: 'gabriel', age: 20 };
const body = 'data=' + JSON.stringify(obj);

this.http.post('/test.php', body, { headers })
  .subscribe(res => console.log(res.json()), res => console.error(res))

字符串
而在php中

$post = json_decode($_POST['data']);

x0fgdtte

x0fgdtte3#

同意你的观点,我们目前不能提供对象而不是字符串。这是一个正在进行中的功能。请看这个问题:

关于你在服务器端获取JSON数据的问题,这个问题应该可以帮助你:

5lhxktic

5lhxktic4#

如果你在2023年还在阅读这本书...我遵循了上面的@Gabriel Martins的回答,这让我大部分时间都在那里...但是在调用中添加'data='是不必要的,因为我选择使用“php://input”。
该项目目前正在开发中,使用Apache,php(8.1),Angular 16。
因此,我的前端调用(使用Angular 16)看起来如下所示:

public createPost(form: any){
    let headers = new HttpHeaders();
    headers.append('Accept', 'application/x-www-form-urlencoded');
    headers.append('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8')
    //method value below is 'createPost'
    let obj = JSON.stringify(Object.assign(form, {method: environment.endpoints.createPost.method}));
    return this.http.post(environment.origin + environment.endpoints.createPost.url, obj, {['headers']: headers}).pipe()
    //At this point, everything is almost the same as Gabriel's answer.
  }

字符串
我的后端代码(使用PDO for mysql)和一个小的自定义库是:

<?php

namespace System;

class Request {
    
    private $headers = [];
    private $method = [];
    private $inputs = [];
    private $files = [];
    
    public static $instance;
    
    public function __construct() {
        self::$instance = $this;
        $this->headers = apache_request_headers();
        $this->method = strtolower($_SERVER['REQUEST_METHOD']);
        
        if($this->method == 'post'){
            //This is one spot where our answers are different. 
            //The addition of 'data=' causes unneeded parsing here. 
            //Just passing a stringified JSON seemed to work better. 
            //Note the second argument for true to json_decode.
            $input = json_decode(file_get_contents("php://input"), true);
            if(isset($this->headers['Content-Type'])){
                $content_type = $this->headers['Content-Type'];

                if($content_type == 'application/x-www-form-urlencoded' || strstr($content_type, 'text/plain')){
                    foreach($input as $key=>$value){
                        $this->inputs[$key] = filter_var($value, FILTER_DEFAULT);
                    }
                }
            }
        }
    }
    /**
     * returns this class instance
     * @return self
     */
    public static function get(){
        if(self::$instance === null){
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * returns the method used to access the current request
     * @return string
     */
    public function get_method() : string{
        return $this->method;
    }
    
    /**
     * returns all the headers in the current request
     * @return array
     */
    public function get_headers() : array{
        return $this->headers;
    }
    
    /**
     * returns the header or null by key
     * @param string $key
     * @return type
     */
    public function get_header(string $key){
        return $this->headers[$key] ?? null;
    }
    
    /**
     * returns the input value in the request or null
     * @param string $var
     * @return type
     */
    public function get_input(string $var){
        return $this->inputs[$var] ?? null;
    }
    
    /**
     * returns all the input fields in the current request
     * @return array
     */
    public function get_all_inputs(): array{
        return $this->inputs;
    }
    
    public function get_files(): array{
        return $this->files;
    }
}
?>


实际调用PDO库的公共API代码是:

<?php
    require_once(__DIR__."/../Models/BlogPosts.php");
    require_once(__DIR__."/../System/Request.php");
    
    $blogModel = new \Models\BlogPost();
    $req = \System\Request::get();
    
    switch($req->get_input('method')){
        case 'createPost':
            print_r($blogModel->createPost(
                $req->get_input('url'),
                $req->get_input('title'),
                $req->get_input('description'),
                $req->get_input('author'),
                $req->get_input('category'),
                $req->get_input('sequence'),
                $req->get_input('image'),
                $req->get_input('imageWebp'),
                $req->get_input('content')
            ));
            break;
        case 'getFullPostByID':
            print_r($blogModel->getFullPostByID($req->get_input('id')));
            break;
        case 'getAllPosts':
            print_r($blogModel->getAllBasicPostInfo());
            break;
    }

?>


无论如何,我希望这能帮助到某人。我还确保在请求URL的末尾附加了一个斜线,以便将请求发送到'API/posts.php/'而不是'api/posts.php'

相关问题