The best design pattern for creating dynamically JSON for API - php

I look for the most efficient and flexible design pattern for creating dynamically JSON that will be my API for IOS.
In example below (its only basic part) "pages", "container", "buttons" and "inputs" are dynamic. Their number and content depends request.
Now I create it that way:
foreach($pages as $page) {
foreach($containers as $container){
foreach($buttons as $burron){
foreach($inputs as $inputs){
}
}
}
}
The result:
{
"callback": {
"status": true,
"message": "",
"return_data": {
"document": {
"number": 6,
"url": "/path/to/file",
"document_id": 11,
"type": 1,
"date": "2017-10-30",
"pages": [
{
"page_number": 1,
"container": [
{
"lp": 1,
"position": 0,
"buttons": [
{
"type": 1,
"header": "Button name",
"inputs": [
{
"type": 0,
"x_pos": 160,
"y_pos": 3441,
"lp": 2
I hope that my question is clear. Thanks for all advice.

The topic that you're describing is called serialization. Basically, it's converting any data structure from one format to another. In your case you want to convert an object or array to JSON. There are several tools in PHP that help with that. For multidimentional arrays or stdClasses, you can use json_encode(). For more complex objects, you can use a serializer library, for example JMS Serializer.

Related

I want a more consolidate json format

I am getting json array after getting applying query logic.
[
{
"id": "3",
"diag_name": "LT Diagnostics",
"test_name": "Alk PO4",
"booking_date": "2018-05-20"
},
{
"id": "3",
"diag_name": "LT Diagnostics",
"test_name": "CRP",
"booking_date": "2018-05-20"
},
{
"id": "4",
"diag_name": "Seepz Diagnostics",
"test_name": "Alk PO4",
"booking_date": "2018-05-21"
}
]
But i want a more justified json array written below.
[
{
"diag_name": "LT Diagnostics",
"test_name": [
{
"id": "3",
"name" : "Alk PO4"
},
{
"id": "3",
"name" : "CRP"
}
],
"booking_date": "2018-05-20"
},
{
"diag_name": "Seepz Diagnostics",
"test_name": [
{
"id": "4",
"name" : "Alk PO4"
}
],
"booking_date": "2018-05-21"
},
]
I am not getting it,How to do in php. I want a more consolidate json format.
Have you tried changing your SQL query to group by diag_name and booking_date? That would be the first step I’d employ to get the outer data.
Formatting the data in the nested manner you’re after could be a function of whatever record serializer you’re using — does it support nested JSON as a return type, or only flat JSON as your example return value shows?
If the record set -> JSON serializer only ever returns flat data, the comments above are correct that you will have to write your own formatter to change the shape of the JSON yourself...
The accepted answer of this other question may be of help:
Create multi-level JSON with PHP and MySQL
I'm not a PHP guy but this is a typical scenario to use functional programming by means of the monad Map.
Looking online I've found this article that could help you.
Changing datasource output is not always (seldom indeed) a viable option.
Enjoy coding

Elasticsearch: What's the best way to search for a word within a string AND get score?

I'm using ElasticSearch's PHP client and I find really difficult to return results with scores whenever I want to search for a word that is "hidden" within a string.
This is an example:
I want to get all the documents where the field "file" has the word "anses" and files are named like this:
axx14anses19122015.zip
What I know about it
I know I should tokenize those words, can't realize how to do it.
Also I've read about aggregations but I'm really new to ES and I have to deliver a working piece ASAP.
What I've tried so far
REGEXP: using regular expressions is very expensive and does not return any scores, which is a must-to-have in order to shrink results and bring the user accurate information.
Wildcards: same thing, slow and no scores
Own script where I have a dictionary and search for critical words using regexp, if match, create a new field within that matched document with the word. The reason is to create a TOKEN so in future searches I can use regular match with scores. Negative side: the dictionary thing was totally denied by my boss so I'm here asking for any ideas.
Thanks in advance.
I suggest in your case nGram tokenizer see the example
I will create a analyzer and a mapping for a doc type
PUT /test_index
{
"settings": {
"number_of_shards": 1,
"analysis": {
"tokenizer": {
"ngram_tokenizer": {
"type": "nGram",
"min_gram": 4,
"max_gram": 4,
"token_chars": [ "letter", "digit" ]
}
},
"analyzer": {
"ngram_tokenizer_analyzer": {
"type": "custom",
"tokenizer": "ngram_tokenizer",
"filter": [
"lowercase"
]
}
}
}
},
"mappings": {
"doc": {
"properties": {
"text_field": {
"type": "string",
"term_vector": "yes",
"analyzer": "ngram_tokenizer_analyzer"
}
}
}
}
}
after that I`ll insert a document using your file name
PUT /test_index/doc/1
{
"text_field": "axx14anses19122015"
}
now I`ll just will use a query match
POST /test_index/_search
{
"query": {
"match": {
"text_field": "anses"
}
}
}
and will receive a reponse like this
{
"took": 8,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.10848885,
"hits": [
{
"_index": "test_index",
"_type": "doc",
"_id": "1",
"_score": 0.10848885,
"_source": {
"text_field": "axx14anses19122015"
}
}
]
}
}
What i did?
i just created a nGram tokenizer that will explode our string in 4 characters terms and will index this terms separated and they will be searched when I search a part of the string.
To see more, read this article https://qbox.io/blog/an-introduction-to-ngrams-in-elasticsearch
Hope it help!
Ok after trying -so- many times it worked. I'll share the solution just in case someone else needs it. Thank you so much to Waldemar, it was a really good approach and I still cannot see why it's not working.
curl -XPUT 'http://ipaddresshere/tokentest' -d
'{ "settings":
{ "number_of_shards": 1, "analysis" :
{ "analyzer" : { "myngram" : { "tokenizer" : "mytokenizer" } },
"tokenizer" : { "mytokenizer" : {
"type" : "nGram",
"min_gram" : "3",
"max_gram" : "5",
"token_chars" : [ "letter", "digit" ] } } } },
"mappings":
{ "doc" :
{ "properties" :
{ "field" : {
"type" : "string",
"term_vector" : "yes",
"analyzer" : "myngram" } } } } }'
Sorry for bad indentation, I'm really hurry but want to post the solution.
So, this will take any string from "field" and split it into nGrams with lenght 3 to 5. For example: "abcanses14f.zip" will result in:
abc, abca, abcan, bca, bcan, bcans, etc... until it reaches anses or a similar term which is matcheable and has a score related to it.

JSON Schema Requirement Enforcement

So this is my first time using JSON Schema and I have a fairly basic question about requirements.
My top level schema is as follows:
schema.json:
{
"id": "http://localhost/srv/schemas/schema.json",
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"event": { "$ref": "events_schema.json#" },
"building": { "$ref": "buildings_schema.json#" }
},
"required": [ "event" ],
"additionalProperties": false
}
I have two other schema definition files (events_schema.json and buildings_schema.json) that have object field definitions in them. The one of particular interest is buildings_schema.json.
buildings_schema.json:
{
"id": "http://localhost/srv/schemas/buildings_schema.json",
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "buildings table validation definition",
"type": "object",
"properties": {
"BuildingID": {
"type": "integer",
"minimum": 1
},
"BuildingDescription": {
"type": "string",
"maxLength": 255
}
},
"required": [ "BuildingID" ],
"additionalProperties": false
}
I am using this file to test my validation:
test.json:
{
"event": {
"EventID": 1,
"EventDescription": "Some description",
"EventTitle": "Test title",
"EventStatus": 2,
"EventPriority": 1,
"Date": "2007-05-05 12:13:45"
},
"building": {
"BuildingID": 1,
}
}
Which passes validation fine. But when I use the following:
test2.json
{
"event": {
"EventID": 1,
"EventDescription": "Some description",
"EventTitle": "Test title",
"EventStatus": 2,
"EventPriority": 1,
"Date": "2007-05-05 12:13:45"
}
}
I get the error: [building] the property BuildingID is required
Inside my buildings_schema.json file I have the line "required": [ "BuildingID" ] which is what causes the error. It appears that the schema.json is traversing down the property definitions and enforcing all the requirements. This is counter intuitive and I would like it to ONLY enforce a requirement if it's parent property is enforced.
I have a few ways around this that involve arrays and fundamentally changing the structure of the JSON, but that kind of defeats the purpose of my attempts at validating existing JSON. I have read over the documentation (/sigh) and have not found anything relating to this issue. Is there a some simple requirement inheritance setting I am missing?
I am using the Json-Schema for PHP implementation from here: https://github.com/justinrainbow/json-schema
After messing with different validators, it appears to be an issue with the validator. The validator assumes required inheritance through references. I fixed this by simply breaking apart the main schema into subschemas and only using the required subschema when necessary.

How may i retrieve Mysql data to this JSON format?

I have read about json_encode but still lack the logic in using it for my needs on this particular JSON structure.
Assuming the JSON structure is as follows :
{
"_id": "23441324",
"api_rev": "1.0",
"type": "router",
"hostname": "something",
"lat": -31.805412,
"lon": -64.424677,
"aliases": [
{
"type": "olsr",
"alias": "104.201.0.29"
}
],
"site": "roof town hall",
"community": "Freifunk/Berlin",
"attributes": {
"firmware": {
"name": "meshkit",
"url": "http:k.net/"
}
}
}
Some of the values of the attributes will be taken from the database while some are going to be hardcoded(static) like "type","api_rev". I was thinking of just using concatenation to build the structure but learnt its a bad idea. So if i am to use json_encode how may i be able to handle this structure ? array dimensions etc.

PHP - regex to reformat JSON

I've been trying to figure out how to reformat multiple JSON files into a single one using php, but am having a difficult time understanding how to use complex regular expressions. Suppose I hade multiple instances of the following JSON data:
{
"felines": {
"cats": [
{
"age": 7,
"name": "frank"
},
{
"age": 4,
"name": "popeye"
}
]
},
"canines": {
"dogs": [
{
"age": 2,
"name": "lucy"
},
{
"age": 12,
"name": "wilson"
}
]
}
}
Lets say I had 2 instances of this JSON object in a php script, and wanted to create a single JSON object that combined both "feline" objects from the two separate JSON instances I had, removing the "canines" objects. The file I'd ultimately want would look like this:
{
"felines": {
"cats": [
{
"age": 7,
"name": "frank"
},
{
"age": 4,
"name": "popeye"
}
]
},
"felines": {
"cats": [
{
"age": 6,
"name": "sam"
},
{
"age": 4,
"name": "kelly"
}
]
}
}
Does anyone know how i might be able splice and combine these JSON objects with regular expressions using php?
Thanks.
why don't you use json_encode & json_decode to do the works on php arrays seems to be a lot more easy then doing that with regular expressions.
I doubt this is a problem you should try to solve with regexes. Consider converting the JSON files to associative arrays, do your merging, and then change back to JSON.
Regular expressions are, in general, really bad at dealing with arbitrarily nested contexts like JSON data, HTML tags, programming languages, etc. Some extended regular expression libraries patch around those deficiencies.
But, really, is there a reason you need to do this in JSON itself? And with regex? You're probably going to have a much easier time deserializing the data to real PHP data structures, and merging/manipulating things there. Then, when you're done, re-serialize the result.
The best way to do it would be as RageZ suggested, using json_encode and json_decode, however JSON doesn't allow you to have the same key name, does it? The best you can get would be this:
{
"felines": {
"cats": [
{
"age": 7,
"name": "frank"
},
{
"age": 4,
"name": "popeye"
},
{
"age": 6,
"name": "sam"
},
{
"age": 4,
"name": "kelly"
}
]
}
}

Categories