I have the structure below which I need to turn into json_encoded. To finally get it decoded and get an object.
This will allow me to have multiple objects with the name message and loop through them and process each message individually.
However when encoded, php will only encode the key and one of the message arrays—the last one.
$setup = [
'key' => 'demo-7hn3fh83un3yhvfjvnjgknfhjnvf',
'message' => [
'number' => [
'+39XXXXXXXX',
'+34XXXXXXXX',
'+49XXXXXXXX'
],
'text' => 'Sample msg 123...',
],
'message' => [
'number' => [
'+50XXXXXXXX',
'+50XXXXXXXX'
],
'text' => 'Something...',
]
];
Is there a way to encode multiple arrays with the same name?
You've overlooked the root issue:
$foo = [
'bar' => 1,
'bar' => 2,
'bar' => 3,
];
var_export($foo);
array (
'bar' => 3,
)
Thanks for the tips everyone. I ended up modifying the structure like below...
The reason why I am going with a structure like this is cause it allows me to submit multiple messages to multiple users with a single request.
$setup = [
'key' => 'demo-7hn3fh83un3yhvfjvnjgknfhjnvf',
'message' => [
[
'number' => [
'+39XXXXXXXX',
'+34XXXXXXXX',
'+49XXXXXXXX'
],
'text' => 'Sample msg 123...'
],
[
'number' => [
'+50XXXXXXXX',
'+50XXXXXXXX'
],
'text' => 'Something...'
]
]
];
Related
I'm trying to perform a basic login operation where my view (front end part) accepts a username and password through a form
So in SQL, I must have an example query:
SELECT * FROM users WHERE username = $_POST['username'] AND password = $_POST['password'];
According to the official documentation of Elasticsearch PHP API, it must go like this:
$params = [
'index' => 'myIndex',
'type' => 'myType',
'body' => [
'query' => [
"bool" => [
"must" => [
"match" => [
"username" => 'email#email.com',
],
"match" => [
"password" => 'mypassword',
],
]
]
]
]
];
Unfortunately, it is displaying A LOT of documents so I presumed it's performing the OR operator instead of matching them together
FYI, if you would ever wonder why would there be so many documents displayed according to the "hits" property above, there are literally many user documents with the same password
Main Question
Is there any proper ES query to properly match my username AND password so I could only retrieve one document? I've been searching through with the official documentation, but nothing succeeds the desired output
Thank you very much!
You're almost there. You need to enclose your match queries in one more array, otherwise your bool/must becomes an associative array and that's not what you want (i.e. the second match filter gets discarded).
$params = [
'index' => 'myIndex',
'type' => 'myType',
'body' => [
'query' => [
"bool" => [
"must" => [
--> [
"match" => [
"username" => 'email#email.com',
]
--> ],
--> [
"match" => [
"password" => 'mypassword',
]
]
--> ]
]
]
]
];
With the help of sir Val, I was able to formulate a technique to try work-arounds for my query, and was able to display the result with the following:
$params = [
'index' => $index,
'type' => 'index',
'size' => 250,
'body' => [
'query' => [
'bool' => [
'must' => [
[
"match" => [
"usr_username" =>
[
"query" => $username,
"operator" => "and"
]
]
],
[
"match" => [
"usr_password" => [
"query" => $password,
"operator" => "and"
]
]
]
]
]
]
]
];
Hello.
I currently have a problem with the AWS Route-53 API. To create a record you need to call a function, which itself needs an array of inputs.
I want to create a record set here and for that I have some POST values. One of them, $_POST['record_value'], is a textarea and has multiple lines. I loop through them. This is to enable multiple values for one record. The code is as follows when you hardcode it as one value in ResourceRecords;
$result = $this->route53->changeResourceRecordSets([
'ChangeBatch' => [
'Changes' => [
[
'Action' => 'CREATE',
'ResourceRecordSet' => [
'Name' => $recordName,
'ResourceRecords' => [
[
'Value' => $recordValue
],
],
'TTL' => $recordTtl,
'Type' => $recordType,
],
],
],
'Comment' => 'Routing Record Set',
],
'HostedZoneId' => $this->zone,
]);
Hower. I want to make ResourceRecords dynamically. For every line in the textarea I need a new set of the following part of the code;
[
'Value' => $recordValue
],
What I thought is the following;
$newData = [];
foreach(explode("\r\n", $recordValue) as $valLine) {
$newData[] = ["Value" => $valLine];
}
$result = $this->route53->changeResourceRecordSets([
'ChangeBatch' => [
'Changes' => [
[
'Action' => 'CREATE',
'ResourceRecordSet' => [
'Name' => $recordName,
'ResourceRecords' => [
$newData
],
'TTL' => $recordTtl,
'Type' => $recordType,
],
],
],
'Comment' => 'Routing Record Set',
],
'HostedZoneId' => $this->zone,
]);
However, this seems to return an exception: Found 1 error while validating the input provided for the ChangeResourceRecordSets operation:↵[ChangeBatch][Changes][0][ResourceRecordSet][ResourceRecords][0] must be an associative array. Found array(1).
Am I building the array wrong or am I doing this wrong alltogether?
$newData is already an array, you don't need to wrap it in another array.
'ResourceRecords' => $newData,
I am using Zend Framework 3 and I'm trying to validate a form with a collection field.
My form has a field
$this->add([
'name' => 'domains',
'options' => [
'target_element' => [
'type' => Text::class
]
],
'type' => Collection::class
]);
When I submit the form I obtain something like this as POST data
[
'domains' => [
0 => 'first'
1 => 'second'
]
]
I am trying to validate this with a CollectionInputFilter like the following
$filter = new InputFilter();
$filter->add([
'type' => CollectionInputFilter::class,
'options' => [
'input_filter' => [
'validators' => [
[
'name' => Hostname::class
]
]
]
]
], 'domains');
$filter->setData($data);
but I obtain the exception Zend\InputFilter\CollectionInputFilter::setData expects each item in a collection to be an array or Traversable; invalid item in collection of type string detected.
What am I doing wrong?
I found out that the error was in using CollectionInputFilter. I should have been using ArrayInput instead.
I am currently developing a skill for Amazon's echo dot which requires the use of persistent data. I ran into an issue when developing a web interface for my skill where I was not able to easily update the mapAttr column of the DynamoDB table used by the skill.
I've been trying to work this out for the last 2 days, I've looked everywhere including the documentation but can't seem to find anything that'll help me.
This is the code I am using:
$result = $client->updateItem([
'TableName' => 'rememberThisDBNemo',
'Key' => [
'userId' => [ 'S' => $_SESSION['userDataAsk'] ]
],
'ExpressionAttributeNames' => [
'#attr' => 'mapAttr.ReminderJSON'
],
'ExpressionAttributeValues' => [
':val1' => json_encode($value)
],
'UpdateExpression' => 'SET #attr = :val1'
]);
I have tried many different things so this might be just absolutely wrong, but nothing that I have found has worked.
The table has 2 columns, userId and mapAttr, userId is a string and mapAttr is a map. Originally I thought it was simply a JSON string but it was not like that as when I tried to update it with a JSON string directly it would stop working when read by Alexa.
I am only trying to update 1 out of the 2 attributes of mapAttr. That is ReminderJSON which is a string.
Any help would be appreciated. Thanks.
Try calling updateItem like this
$result = $client->updateItem([
'TableName' => 'rememberThisDBNemo',
'Key' => [
'userId' => [ 'S' => $_SESSION['userDataAsk'] ]
],
'ExpressionAttributeNames' => [
'#mapAttr' => 'mapAttr',
'#attr' => 'ReminderJSON'
],
'ExpressionAttributeValues' => [
':val1' => ['S' => json_encode($value)]
],
'UpdateExpression' => 'SET #mapAttr.#attr = :val1'
]);
However, please be aware that in order for this to work, attribute mapAttr must already exist. If it doesn't, you'll get ValidationException saying The document path provided in the update expression is invalid for update...
As a workaround, you may want to add a ConditionExpression => 'attribute_exists(mapAttr)' to your params, catch possible exception, and then perform another update adding a new attribute mapAttr:
try {
$result = $client->updateItem([
'TableName' => 'rememberThisDBNemo',
'Key' => [
'userId' => [ 'S' => $_SESSION['userDataAsk'] ]
],
'ExpressionAttributeNames' => [
'#mapAttr' => 'mapAttr'
'#attr' => 'ReminderJSON'
],
'ExpressionAttributeValues' => [
':val1' => ['S' => json_encode($value)]
],
'UpdateExpression' => 'SET #mapAttr.#attr = :val1'
'ConditionExpression' => 'attribute_exists(#mapAttr)'
]);
} catch (\Aws\Exception\AwsException $e) {
if ($e->getAwsErrorCode() == "ConditionalCheckFailedException") {
$result = $client->updateItem([
'TableName' => 'rememberThisDBNemo',
'Key' => [
'userId' => [ 'S' => $_SESSION['userDataAsk'] ]
],
'ExpressionAttributeNames' => [
'#mapAttr' => 'mapAttr'
],
'ExpressionAttributeValues' => [
':mapValue' => ['M' => ['ReminderJSON' => ['S' => json_encode($value)]]]
],
'UpdateExpression' => 'SET #mapAttr = :mapValue'
'ConditionExpression' => 'attribute_not_exists(#mapAttr)'
]);
}
}
I've just downloaded and installed the last version of Elasticsearch on my Windows machine. I did my first search queries and everything seemed to work ok. However. when I try to highlight the search results, I fail. So, this is how my query looks like:
$params = [
'index' => 'test_index',
'type' => 'test_index_type',
'body' => [
'query' => [
'bool' => [
'should' => [ 'match' => [ 'field1' => '23' ] ]
]
],
'highlight' => [
'pre_tags' => "<em>",
'post_tags' => "</em>",
'fields' => (object)Array('field1' => new stdClass),
'require_field_match' => false
]
]
]
$res = $client->search($params);
On the whole the query itself works nice - the results are filtered. In the console I see, that all documents indeed contain "23" value in their field1 field. However, these tags - <em></em> are simply not added to the result. What I see is just the raw value in field1 like "some text 23", "23 another text". It is not what I expect to see - "some text <em>23</em>", "<em>23</em> another text". So, what is wrong with that and how can I fix it?
From the manual:
The value of pre_tags and post_tags should be an array (however if you don't want to change the em tags you can ignore them, they already set as default).
The fields value should be an array, key is the field name and the value is an array with the field options.
Try this fix:
$params = [
'index' => 'test_index',
'type' => 'test_index_type',
'body' => [
'query' => [
'bool' => [
'should' => [ 'match' => [ 'field1' => '23' ] ]
]
],
'highlight' => [
// 'pre_tags' => ["<em>"], // not required
// 'post_tags' => ["</em>"], // not required
'fields' => [
'field1' => new \stdClass()
],
'require_field_match' => false
]
]
];
$res = $client->search($params);
var_dump($res['hits']['hits'][0]['highlight']);
update
Did a double check, the value of the field in the fields array should be an object (which is a requirement, not exactly the same as other options).
The pre/post_tags can also be strings (and not array).
Did you check the correct response? $res['hits']['hits'][0]['highlight']
The important thing to notice is that the highligted results goes into the highlight array - $res['hits']['hits'][0]['highlight'].