Poste HTTP angulaire vers PHP et indéfini

J'ai un formulaire avec le tag ng-submit="login()

La fonction est appelée bien en javascript.

 function LoginForm($scope, $http) { $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'; $scope.email = "[email protected]"; $scope.password = "1234"; $scope.login = function() { data = { 'email' : $scope.email, 'password' : $scope.password }; $http.post('resources/curl.php', data) .success(function(data, status, headers, config) { console.log(status + ' - ' + data); }) .error(function(data, status, headers, config) { console.log('error'); }); } } 

Je reçois une réponse de 200 OK du fichier PHP, mais les données renvoyées indiquent que le email et le password sont indéfinis. C'est tout le php que j'ai

 <?php $email = $_POST['email']; $pass = $_POST['password']; echo $email; ?> 

Une idée de pourquoi je reçois des valeurs POST indéfinies?

MODIFIER

Je voulais souligner, car cela semble être une question populaire (pourtant, elle est ancienne), .success et .error ont été obsolètes et vous devriez utiliser. .then que @James Gentes a souligné dans les commits

Angularjs .post() défaut l'en-tête Content-type à application/json . Vous supprimez ceci pour transmettre des données codées par formulaire, mais vous ne modifiez pas votre valeur de data pour passer une chaîne de requête appropriée, donc PHP ne $_POST pas $_POST comme vous l'attendez.

Ma suggestion serait d'utiliser simplement le paramètre angularjs par défaut d' application/json comme en-tête, de lire l'entrée brute en PHP, puis de désérialiser le JSON.

Cela peut être réalisé en PHP comme ceci:

 $postdata = file_get_contents("php://input"); $request = json_decode($postdata); $email = $request->email; $pass = $request->password; 

Alternativement, si vous [email protected]&password=somepassword fortement $_POST fonctionnalité $_POST , vous pouvez former une chaîne de requête comme [email protected]&password=somepassword et l'envoyer en tant que données. Assurez-vous que cette chaîne de requête est codée par URL. Si construit manuellement (par opposition à utiliser quelque chose comme jQuery.serialize() ), Javascript encodeURIComponent() devrait faire l'affaire pour vous.

Je le fais sur le côté du serveur, au début de mon fichier d'initialisation, fonctionne comme un charme et vous n'avez pas à faire quoi que ce soit dans le code php angulaire ou existant:

 if ($_SERVER['REQUEST_METHOD'] == 'POST' && empty($_POST)) $_POST = json_decode(file_get_contents('php://input'), true); 

Dans l'API que je développe, j'ai un contrôleur de base et, dans sa méthode __construct (), j'ai le suivant:

 if(isset($_SERVER["CONTENT_TYPE"]) && strpos($_SERVER["CONTENT_TYPE"], "application/json") !== false) { $_POST = array_merge($_POST, (array) json_decode(trim(file_get_contents('php://input')), true)); } 

Cela me permet de simplement référencer les données json en tant que $ _POST ["var"] au besoin. Fonctionne très bien.

De cette façon, si un utilisateur authentifié se connecte à une bibliothèque comme un jQuery qui envoie des données de publication avec un type de contenu par défaut: application / x-www-form-urlencoded ou Content-Type: application / json, l'API répondra sans erreur et Rendre l'API un peu plus amiable pour les développeurs.

J'espère que cela t'aides.

Code de démo angulaire Js: –

 angular.module('ModuleName',[]).controller('main', ['$http', function($http){ var formData = { password: 'test pwd', email : 'test email' }; var postData = 'myData='+JSON.stringify(formData); $http({ method : 'POST', url : 'resources/curl.php', data: postData, headers : {'Content-Type': 'application/x-www-form-urlencoded'} }).success(function(res){ console.log(res); }).error(function(error){ console.log(error); }); }]); 

Code côté serveur: –

 <?php // it will print whole json string, which you access after json_decocde in php $myData = json_decode($_POST['myData']); print_r($myData); ?> 

En raison du comportement angulaire, il n'y a pas de méthode directe pour le comportement de publication normal au serveur PHP, donc vous devez le gérer dans les objets json.

Parce que PHP n'accepte pas de manière native 'application/json' JSON 'application/json' Une approche consiste à mettre à jour vos en-têtes et vos paramètres de manière angulaire afin que votre api puisse utiliser les données directement.

D'abord , paramétrer vos données:

 data: $.param({ "foo": $scope.fooValue }) 

Ensuite , ajoutez ce qui suit à votre $http

  headers: { 'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8' }, 

Si toutes vos demandes vont au PHP, les paramètres peuvent être définis globalement dans la configuration comme suit:

 myApp.config(function($httpProvider) { $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'; }); 

Vous devez désérialiser vos données de formulaire avant de la passer comme second paramètre à .post (). Vous pouvez le faire en utilisant la méthode $ .param (données) de jQuery. Ensuite, vous serez en mesure de le faire référence comme $ .POST ['email'];

C'est la meilleure solution (IMO) car il ne nécessite aucun décalage jQuery et JSON:

Source: https://wordpress.stackexchange.com/a/179373 et: https://stackoverflow.com/a/1714899/196507

Résumé:

 //Replacement of jQuery.param var serialize = function(obj, prefix) { var str = []; for(var p in obj) { if (obj.hasOwnProperty(p)) { var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p]; str.push(typeof v == "object" ? serialize(v, k) : encodeURIComponent(k) + "=" + encodeURIComponent(v)); } } return str.join("&"); }; //Your AngularJS application: var app = angular.module('foo', []); app.config(function ($httpProvider) { // send all requests payload as query string $httpProvider.defaults.transformRequest = function(data){ if (data === undefined) { return data; } return serialize(data); }; // set all post requests content type $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'; }); 

Exemple:

 ... var data = { id: 'some_id', name : 'some_name' }; $http.post(my_php_url,data).success(function(data){ // It works! }).error(function() { // :( }); 

Code PHP:

 <?php $id = $_POST["id"]; ?> 

C'est une vieille question, mais il vaut la peine de mentionner que dans Angular 1.4 $ httpParamSerializer est ajouté et lorsque vous utilisez $ http.post, si nous utilisons $ httpParamSerializer (params) pour passer les paramètres, tout fonctionne comme une demande de publication régulière et aucune désérialisation JSON n'est Nécessaire sur le côté serveur.

https://docs.angularjs.org/api/ng/service/$httpParamSerializer

Il m'a fallu des heures pour comprendre que tout en travaillant avec Angular et PHP. Les données de publication n'étaient pas vers PHP en $ _POST

Dans le code PHP, procédez comme suit. – Créez une variable $ angular_post_params – Ensuite, faites les $angular_http_params = (array)json_decode(trim(file_get_contents('php://input')));

Maintenant vous pouvez accéder à vos paramètres comme vous le faites à partir de $ _POST

$angular_http_params["key"]

Au cas où vous vous demandiez au sujet de javascript … c'est ce que j'ai utilisé

  var myApp = angular.module('appUsers', []); //var post_params = $.param({ request_type: "getListOfUsersWithRolesInfo" }); var dataObj = { task_to_perform: 'getListOfUsersWithRolesInfo' }; myApp.controller('ctrlListOfUsers', function ($scope, $http) { $http({ method: 'POST', dataType: 'json', url: ajax_processor_url, headers: { 'Content-Type': 'application/json' }, data: dataObj, //transformRequest: function(){}, timeout: 30000, cache: false }). success(function (rsp) { console.log("success"); console.log(rsp); }). error(function (rsp) { console.log("error"); }); });