This is quite a novice question - I've looked at similar solutions to similar problems on here and around the internet however I can't seem to find what the problem is with this one.
I'm playing with PHP and writing a bit of code that pulls all of the mailing data out of an API. However I noticed that load times were very very slow and that was because for each mail's contents I was doing a separate query. I've since figured out how to pull what I'm looking for in one go however I'm having trouble adding the data thats returned to my 2D array that i'm storing the data in before its output.
Here is my array below;
$mailMessage = array(
array(
'mailNumber' => $mailCount,
'mailID' => $mailID,
'mailDate' => $mailDate,
'mailSender' => $mailSender,
'mailSenderName' => null,
'mailMsg' => null
));
And here is how I'm trying to update said array;
foreach ($mailMessage as &$row){
if($row['mailID'] == $getMailID){
$row['mailMsg'] = $body;
break;
}
}
So I'm checking if the mailID is the same as the one that i'm currently looking at, then if it is i'm trying to update the mailMsg part of the array on that line to be $body. I've checked the
This however is not working. No PHP error messages are flagging up - (Some times this is worse!) and i'm pretty much hitting my head off of a brick wall.
Thanks for reading & for your time,
Jamie
Is there a reason you're using a multidimensional array instead of just an associative? You're not iterating over any indexes because there aren't any present within the aggregated array format. The correct format should be :
Multidimension :
$mailMessage = array(
0 => array(
'mailNumber' => $mailCount,
'mailID' => $mailID,
'mailDate' => $mailDate,
'mailSender' => $mailSender,
'mailSenderName' => null,
'mailMsg' => null
)
);
Associative :
$mailMessage = array(
'mailNumber' => $mailCount,
'mailID' => $mailID,
'mailDate' => $mailDate,
'mailSender' => $mailSender,
'mailSenderName' => null,
'mailMsg' => null
);
Related
I have 2 arrays. The first array contains the correct word variants and the second array contains incorrect word variants. I want to write them by combining into one as an array, passing in the wrong version of the words to the key and to the value of the correct version of the word. Then write them to a file and use it. I saved the contents of the array in a file, but with a new record to the same file, all the data is cleared and only new entries are re-written and the old entries are deleted automatically. I want that before writing new data to an array, the array is checked for duplication and if such is not written in the file with the array, then let it be written to the file without clearing the previous data of the file. In general, that will select a file or database for storing more than a billion words. Does the database have the best speed or file?
Example first array:
$uncorrect = array
(
0 => "мувосокори",
1 => "мунаггас",
2 => "мангит",
3 => "мангития",
4 => "мунфачир",
5 => "мунфачира",
6 => "манфиатпарасти",
7 => "манфиатчу",
8 => "манфиатчуи",
9 => "манфиатхох",
10 => "манфи",
.....................
);
Example second array:
$correct = array
(
0 => "мувосокорӣ",
1 => "мунағғас",
2 => "манғит",
3 => "манғития",
4 => "мунфаҷир",
5 => "мунфаҷира",
6 => "манфиатпарастӣ",
7 => "манфиатҷӯ",
8 => "манфиатҷӯӣ",
9 => "манфиатхоҳ",
10 => "манфӣ",
.....................
);
I combined two arrays with this code:
$dict = array_combine($uncorrect, $correct);
Example result my array with data here:
$dict = array (
"мувосокори" => "мувосокорӣ",
"мунаггас" => "мунағғас",
"мангит" => "манғит",
"мангития" => "манғития",
"мунфачир" => "мунфаҷир",
"мунфачира" => "мунфаҷира",
"манфиатпарасти" => "манфиатпарастӣ",
"манфиатчу" => "манфиатҷӯ",
"манфиатчуи" => "манфиатҷӯӣ",
"манфиатхох" => "манфиатхоҳ",
"манфи" => "манфӣ",
"минкор" => "минқор",
.....................................
);
I am writing to a file with this code:
file_put_contents("data.json", json_encode($dict));
I will get the array with this code:
$array = json_decode(file_get_contents("data.json"));
You would be better off using a database for this task.
To solve your issue if you decide to keep with the file storage, the reason you are losing old entries is because you forgot to load them before adding new values.
// more or less something like below
$array = json_decode(file_get_contents("data.json"));
$dict = array_combine($incorrect, $correct);
$newArray = array_merge($array, $dict);
file_put_contents("data.json", json_encode($newArray));
This will not be efficient for billions or rows, especially if it's something that gets loaded every time a user loads a page.
Any time you want to add new items just load the file first, then merge the new items in before saving it again. file_put_contents is going to overwrite whatever was there, so you need to get that data before running that function. Something like this:
$array = json_decode(file_get_contents("data.json"));
$newArray = array(
array( "rightWord" => "wrongWord")
);
$finalArray = array_merge($newArray, $array);
file_put_contents("data.json", json_encode($finalArray));
This is driving me mad.. I have a PHP script that returns an array in the form $key => $value and I want to rename the key so that I can display it in a table header. I saw there are several ways of doing this but I'm not sure they are what I need... Either that or I haven't understood the examples correctly which is the likely problem.
Basically my array keys differ each time I iterate over a foreach loop and also some can be blank. How can I get round this?
The first output might look like this:
'_can_chaccess' => false,
'_can_chown' => false,
'_can_delete' => false,
'_can_modify' => false,
'_can_read' => true,
'assigned_to_name_879' => 'Unassigned',
'id' => 1,
'type' => 'Private::Reporting::DataViewModel::DataView_223_42858',
'type_877' => 'Email',
The next run through, I might get this:
'_can_chaccess' => false,
'_can_chown' => false,
'_can_delete' => false,
'_can_modify' => false,
'_can_read' => true,
'assigned_to_name_793' => 'Consultants',
'id' => 1,
'object_reference_794' => 'CASE-1004',
'summary_795' => 'Deployment of New System for HQ (Project)',
'type' => 'Private::Reporting::DataViewModel::DataView_200_42858',
),
As you can see, some keys rename the same e.g. id, type. But the most important ones that I am interested in change each time e.g. Assigned To Name.
Any ideas?
Where do you receive your data from?
You can either somehow modify the source of your data, so if it were a query (what I do not assume here), you have the SELECT ... AS ... statement.
First you do need to know how to interpret the changing keys. If e.g. "assigned_to_name_879" and "assigned_to_name_793" is the same field, you can define a canonical function, which mapps both inputs to a unique output.
The output of the cannonical function and as well the other array keys can serve as keys for an additional array, which contains the table headers of your output.
So your current array is the value's array, and by hand you define a header's array:
array(
'assigned_to_name_879' => 'Name assignment'
);
This dynamic way of storing the table headers in an array only makes sense if you are using the array twice. Otherwise you could simply write the header in the html-code which you do output.
I've managed to figure it out using the below:
$mappings_array = array();
foreach ($report['data'][0] as $key => $value) {
$workbooks->log('Old Key', $key);
preg_match_all('([^_\d]+)', $key, $new_key);
$workbooks->log('New Key', $new_key);
$str = implode(" ", $new_key[0]);
$capitalised = ucwords($str);
array_push($mappings_array,$capitalised);
}
Maybe it's not the best solution but it works :) I get the following output:
> New array: «array (
0 => 'Can Chaccess',
1 => 'Can Chown',
2 => 'Can Delete',
3 => 'Can Modify',
4 => 'Can Read',
5 => 'Id',
6 => 'Total Type',
7 => 'Type',
8 => 'Type',
)
I've come across an odd problem using CakePHP 1.3 to find information. Let's use this dbschema as an example:
id is int(11) PRIMARY auto_increment
amount is float(10,2) NULL
status is ENUM(Completed, Removed, Pending)
id amount status
1 100.00 Completed
2 100.00 Removed
3 100.00 Completed
4 100.00 Completed
5 100.00 Pending
When using Cake's find to retrieve data from this table, I use this query:
$this->Testtable->find('all', array(
'conditions' => array(
'status LIKE ' => 'Removed',
'status LIKE ' => 'Pending',
'status LIKE ' => 'Completed'
)
))
Looking at this query, I would assume that Cake would return all rows that match all of those conditions (which is totally acceptable in SQL), however it only uses the last condition and returns WHERE status LIKE 'Completed'.
I ran a test doing this, which returned all rows correctly (I know it's a more "correct" way to do the query anyway):
'conditions' => array(
'status' => array('Removed', 'Pending', 'Completed')
)
Take the opposite for an example, I want to return all rows that aren't Removed or Pending:
'conditions' => array(
'status !=' => 'Removed',
'status !=' => 'Pending'
)
This query returns all rows with Completed and Removed, as it only listens to the last statement. I assume that this is happening because instead of concatenating these search conditions into the query, Cake is overwriting the conditions based on the "field" being status !=. I can prove this theory by adding a space after the != in either of those conditions, creating the desired result of only Confirmed records.
Can anybody tell me why Cake would do this? As this is a legitimate thing to do in SQL, I see no reason that Cake wouldn't allow you to do it. Does anybody know if this issue is fixed up in newer versions of Cake?
I suppose that this comes down to the fact that at the end of the day, I am reassigning the array value based on that key, and it's not actually CakePHP's fault at all. I had a look into Cake's model.php and found this:
$query = array_merge(compact('conditions', 'fields', 'order', 'recursive'), array('limit' => 1));
I ran a test:
$array = array(
'conditions' => array(
'test' => 'yes',
'test' => 'no'
)
);
$var = 'hello';
$c = compact('array', 'var');
print_r($c);
As mentioned above, compact is only receiving the value no from the test key. I assumed that the use of compact to merge variables/arrays into the query would recursively merge similar keys from the conditions array into the last specified, but it turns out that yes isn't even making it that far as it's being redefined on the spot.
I suppose this is a limitation of PHP rather than Cake, but it is still something that didn't occur to me and should be done differently somehow (if it hasn't already) in future.
Edit
I ran a couple more tests. I wrapped identical conditions in their own arrays, then compared them the way Cake's find functions would. Using compact (which Cake does) the arrays containing identical keys remain intact, however using array_merge, the first key is overwritten by the second. I guess in this case it's a very, very good thing that Cake uses compact instead of array_merge to merge its query criteria.
$array = array(
array('test' => 'yes'),
array('test' => 'no')
);
$m = array_merge($array[0], $array[1]);
$c = compact('array');
print_r($c);
print_r($m);
Result:
Array
(
[array] => Array
(
[0] => Array
(
[test] => yes
)
[1] => Array
(
[test] => no
)
)
)
Array
(
[test] => no
)
While this is obviously a simple problem in the way you fundamentally write PHP code, it wasn't inherently obvious while writing in Cake syntax that conditions would overwrite each other...
Basic PHP: Don't use the same array key twice
'conditions' => array(
'status LIKE ' => 'Removed',
'status LIKE ' => 'Pending',
'status LIKE ' => 'Completed'
)
should be
'conditions' => array(
'status LIKE' => array('Removed', 'Pending', 'Completed'),
)
Same for any other array key.
Note that some quick debugging of the array reveals this.
Please also see the tons of other stackoverflow questions with the same issue or other areas where basic research could have pointed you in this direction. Taking a look there first can help to resolve the issue in less time.
I'm querying a DynamoDB table using the method described here in the AWS PHP developer guide.
The array that I pass to the Dynamo connection looks like the following:
Array(
[ConsistentRead] => false
[TableName] => bbq_lol_test
[KeyConditions] => Array(
[stinky_cheese] => Array(
[ComparisonOperator] => EQ
[AttributeValueList] => Array(
[S] => camembert)
)
)
)
As you can see, it's in the exact format that the example uses, with the exception of the Type enum (which is just a string).
When executing $connection->query with the above array as an argument, I get the following exception:
Guzzle\Service\Exception\ValidationException:
Validation errors: [KeyConditions][stinky_cheese][AttributeValueList][S][AttributeValue] must be of type object
Which is odd, because the array in the stack trace appears to be fine:
Aws/Common/Client/AbstractClient.php(103): Guzzle\Service\Client->__call("Query", array(array("ConsistentRead" => false, "TableName" => "bbq_lol_test", "KeyConditions" => array("stinky_cheese" => array("ComparisonOperator" => "EQ", "AttributeValueList" => array("S" => "camembert"))))))
I DO have an index on the stinky_cheese field (since I'm using query). I'm probably doing something daft, but I can't seem to figure it out now. Any help would be appreciated - thanks!
There were two problems.
First, AttributeValueList should be an array of arrays, not a single array, going from this:
[AttributeValueList] => Array([S] => camembert)
To this:
[AttributeValueList] => Array(Array([S] => camembert))
Since it's possible to add more stuff in there, like so:
[AttributeValueList] => Array(Array([S] => camembert), Array([S] => bleu))
The second problem was that I always have to query using the primary hash key, which I was not doing.
I'm probably missing something simple here but I can't seem to find a way to build a query that will allow me to update a match in a group of nested values.
I have a document like this for a blog app I've been working on (currently uses MySQL):
array (
'_id' => new MongoId("4bc8dcee8ba936a8101a0000"),
'created' => '20100418-201312 +0000',
'post-title' => 'Some Post Title',
'post-body' => 'Blah Blah Blah Blah.',
'post-blog-name' => 'default',
'post-comments' =>
array (
0 =>
array (
'comment-title' => 'Test1',
'comment-body' => 'asdf1',
'created' => '20100418-214512 +0000',
'owner' => 'User1',
),
1 =>
array (
'comment-title' => 'Test2',
'comment-body' => 'asdf2',
'created' => '20100418-214512 +0000',
'owner' => 'User2',
),
),
'owner' => 'zach',
'updated' => '20100418-201312 +0000',
)
I'd like to be able to build a query that can search 'comment-title' for a match and then allow me to update/change/delete data as needed.
Obviously I can perform an update using a query which includes the key value. Something like this works:
$collection->update(
array("post-comments.0.comment-title" => $_POST['comment-title']),
array('$set' => array('entries.0' => array('comment-title' => $_POST['comment-title'], 'comment-body' => $_POST['comment-body'], 'owner' => $_SESSION['username'], 'updated' => gmdate('Ymd\-His O')))));
But I expect I'm missing something that would allow me to leave out the key and still be able to match one of the nested arrays based on a value (in this example the 'comment-title').
Anyway, sorry, this probably isn't the best example and I probably will end up using the keys in comments to identify them (comment #) but since nesting and creating rather complex objects seem to be a few of Mongodbs strong points I'm just hoping someone can point out what it is I might be missing.
A query to remove or update all comments by a specific user (say a user the blog author just black-listed) might be a better example. I'm not sure how I'd do this short of pulling out the entire document and then iterating through the nested arrays using PHP.
try ... notice I removed the "key"
$collection->update(array("post-comments.comment-title" ...
Cheers!