Ich bin dabei, eine REST-API zu erstellen und alle Daten werden als JSON zurückgegeben. Jede Anfrage wird über eine einzige Funktion ausgeführt, die HTTP-Statuscodes setzt, Nachrichten oder Daten zurückgibt, Header setzt usw. Ich erlaube Benutzern auch, einen ?fields=
Parameter hinzuzufügen, wo sie angeben können, welche Felder zurückgegeben werden sollen (zB ?fields=id,hostnames,ip_addresses
) Wenn der Parameter nicht vorhanden ist, erhalten sie natürlich alle zurückgegebenen Daten. Die Funktion, die dies tut, ist auch Teil der Funktion erwähnt Earler, die die Header/Daten/Nachrichten, etc. setzt Was ich in der Lage sein soll zu ermöglichen ist der Benutzer Feldnamen mit Punktnotation angeben, so dass sie Felder von etwas angeben können anderes als ein Feld der obersten Ebene. So zum Beispiel habe ich eine Struktur wie folgt aus:PHP - Erstellen Sie ein neues Array mit der Liste der Array-Schlüssel in Punktnotation
{
"id": "8a2b449111b449409c465c66254c6fcc",
"hostnames": [
"webapp1-sfo",
"webapp1-sfo.example.com"
],
"ip_addresses": [
"12.26.16.10",
"ee80::ae56:2dff:fd89:7868"
],
"environment": "Production",
"data_center": "sfo",
"business_unit": "Operations",
"hardware_type": "Server",
"currently_in_maintenance": false,
"history": [
{
"id": 58,
"time_start_utc": "2013-01-27 00:40:00",
"time_end_utc": "2013-01-27 01:45:00",
"ticket_number": "CHG123456",
"reason": "January production maintenance",
"links": [
{
"rel": "self",
"link": "https://localhost/api/v1/maintenances/58"
}
]
},
{
"id": 104,
"time_start_utc": "2013-02-25 14:36:00",
"time_end_utc": "2013-02-25 18:36:00",
"ticket_number": "CHG456789",
"reason": "February production maintenance",
"links": [
{
"rel": "self",
"link": "https://localhost/api/v1/maintenances/104"
}
]
},
{
"id": 143,
"time_start_utc": "2013-03-17 00:30:00",
"time_end_utc": "2013-03-17 01:55:00",
"ticket_number": "CHG789123",
"reason": "March production maintenance",
"links": [
{
"rel": "self",
"link": "https://localhost/api/v1/maintenances/143"
}
]
}
]
}
Mit Hilfe dieser Funktion kann ich Top-Level-Felder herausziehen (wobei $mData
die Datenstruktur oben ist, und $sParams
ist die Zeichenfolge der Felder vom Benutzer angefordert) :
private function removeFields($mData, $sParams){
$clone = $mData; // Clone the original data
$fields = explode(',', $sParams);
// Remove fields not requested by the user
foreach($mData as $key => $value){
if(!in_array((string)$key, $fields)){
unset($mData[$key]);
}
}
// If no fields remain, restore the original data
// Chances are the user made a typo in the fields list
if(count($mData) == 0){
$mData = $clone;
}
return $mData;
}
Hinweis: $sParams
in als String kommt und ist das, was durch den Benutzer zur Verfügung gestellt wird (comma Liste der Felder, die sie sehen möchten getrennt).
So ?fields=hostnames,history
zurückkehren würde:
{
"hostnames": [
"webapp1-sfo",
"webapp1-sfo.example.com",
],
"history": [
{
"id": 58,
"time_start_utc": "2013-01-27 00:40:00",
"time_end_utc": "2013-01-27 01:45:00",
"ticket_number": "CHG123456",
"reason": "January production maintenance",
"links": [
{
"rel": "self",
"link": "https://localhost/api/v1/maintenances/58"
}
]
},
{
"id": 104,
"time_start_utc": "2013-02-25 14:36:00",
"time_end_utc": "2013-02-25 18:36:00",
"ticket_number": "CHG456789",
"reason": "February production maintenance",
"links": [
{
"rel": "self",
"link": "https://localhost/api/v1/maintenances/104"
}
]
},
{
"id": 143,
"time_start_utc": "2013-03-17 00:30:00",
"time_end_utc": "2013-03-17 01:55:00",
"ticket_number": "CHG789123",
"reason": "March production maintenance",
"links": [
{
"rel": "self",
"link": "https://localhost/api/v1/maintenances/143"
}
]
}
]
}
Aber wenn ich aus history
vielleicht auch nur das ticket_number
Feld zurückkehren wollen möchte ich den Benutzer in der Lage sein ?fields=history.ticket_number
zu tun, oder wenn sie die Ticketnummer und Link wollen sie konnten tun sie dies: ?fields=history.ticket_number,history.links.link
..., die zurückkehren würde:
{
"history": [
{
"ticket_number": "CHG123456",
"links": [
{
"link": "https://localhost/api/v1/maintenances/58"
}
]
},
{
"ticket_number": "CHG456789",
"links": [
{
"link": "https://localhost/api/v1/maintenances/104"
}
]
},
{
"ticket_number": "CHG789123",
"links": [
{
"link": "https://localhost/api/v1/maintenances/143"
}
]
}
]
}
ich viele verschiedene Array-Zugriffsmethoden für Punktnotation von Stack-Überlauf, aber sie alle brechen, wenn der Wert von 012 versucht haben,ist ein numerisches Array ... also zum Beispiel mit den Methoden, die ich bisher online gefunden habe, müsste ich etwas tun, um die gleiche Ausgabe oben zu erreichen (was offensichtlich nicht gut ist ... besonders wenn Sie Hunderte haben von Aufzeichnungen).
?fields=history.0.ticket_number,history.0.links.0.link,history.1.ticket_number,history.1.links.0.link,history.2.ticket_number,history.2.links.0.link,
ich auch der Suche nach etwas war, das dynamische und rekursive war als jeder API-Endpunkt eine andere Datenstruktur (zum Beispiel zurückgibt, wenn eine Sammlung angefordert wird, es gibt einen numerischen Array mit assoziativen arrays..or gefüllt Ein Array von Objekten ... und einige dieser Objekte können Arrays (numerisch oder assoziativ) haben.
Vielen Dank im Voraus
P.S. - Es ist mir egal, ob der Code ein neues Datenarray mit den angeforderten Daten erstellt oder die Originaldaten direkt manipuliert (wie in meiner removeFields() - Funktion).
AKTUALISIERUNG: Ich habe eine PHPFiddle erstellt, die hoffentlich das Problem zeigen sollte, in das ich hineingeraten bin. http://phpfiddle.org/main/code/tw1i-qu7s
Also, um klar zu sein, benötigen Sie PHP, um eine GET-Anfrage zu analysieren, die vielleicht Punkt-abgegrenzte Niveaus hat oder nicht, dann nur diese Aufzeichnungen zurückgeben? – amflare
Ja, das ist richtig. Ein Benutzer kann einen optionalen 'fields'-Parameter über GET bereitstellen, der auf der Serverseite mit PHP verarbeitet wird. Wenn es bereitgestellt wird, kann es eine durch Kommas getrennte Liste von Feldern der obersten Ebene enthalten ('? Felder = Hostnamen, Datencenter, History') oder eine Punkt-begrenzte Liste von Werten, um Daten auf einer niedrigeren Ebene zu extrahieren ('? Fields = history. id, history.ticket_number') oder beide ('? fields = Hostnamen, data_centers, history.ticket_number'). Grundsätzlich könnte der Benutzer eine beliebige Kombination von verfügbaren Array-Schlüsseln bereitstellen, die jeweils durch ein Komma getrennt sind .... welches ich dann zu einem Array explodiere und verarbeite. – Brad