PHP array element starting with "<" weird behavior - php

I was trying to create some syntax for my application that uses $operator.$columnField as elements of an array for SELECT WHERE clause - something like selecting all ids less than 41 would have been
$parameters['where'] = array('<id'),
$parameters['fields'] = array(':id' => '41')
Then I would have parsed all ['where']s in order to determine the operator from the field itself. The main idea here is not if my way is a good way, given the fact that I can do it in a lot of different approaches. I am interested in the fact that it seems '<' plays some specific role if at the beginning of an array element of type string.
I noticed that there were some errors, so I started testing. Now can anyone tell me why
print_r(array('alfa', '<beta', 'gamma'));
echoes
Array (
[0] => alfa
[1] => gamma
)
Thanks in advance.
Later Edit: If the '<' character is followed by a space, the same does not apply any longer. It simply outputs
Array (
[0] => alfa
[1] => < beta
[2] => gamma
)

It actually works.. The < tag is intrepreted by the browser and it is hiding it from you.
Click Ctrl+U to view the source. You will see this..
Array
(
[0] => alfa
[1] => <beta
[2] => gamma
)
Well , if you want it for display purposes.. Do like this..
<?php
print_r(array_map('htmlentities',array('alfa', '<beta', 'gamma')));

Related

PHP - how to fix the weird sort order of SCANDIR_SORT

I am developing a news form where you can enter text and autor and submit it to a blog. After submit a file is created with the following naming convention: newsCounter_date.html, e.g. 121_01_06_2018-093334.html
newsCounter is a value which I increment after every submit, date is the current date.
If someone loads the blog then all news entries are loaded via php, but first they are getting sorted so the latest news entry is on top. I am sorting like this:
$allFiles = array_diff(
scandir("news", SCANDIR_SORT_DESCENDING),
array('..', '.')
);
Everything worked fine, until I reached the 10. blog post, then something weird happened. Instead of the 10. post appearing at the top, it appeared somewhere at the bottom.
I noticed that the sorting does not work anymore, and it does behave completly else in my IDE than in windows. Look at this:
On Windows it goes from 0 -> 12, but in my NetBeans IDE it goes like this: 0 -> 10 -> 11 -> 12 -> 2 -> 3 -> 4 ... so I think NetBeans sort does work like SCANDIR_SORT
Hint: 1 is missing.
Is there another sort method than SCANDIR_SORT_DESCENDING which works like
the windows sort?
How can I solve this problem?
Do you have to use a numeric prefix?
If you just changed the file names to Y-m-d H:m:s.html I believe the order would sort itself out (because both alphabetical and natural sorting would order this the same way) e.g.:
2018-01-06 09:04:37.html
2018-01-06 02:34:04.html
2018-01-05 22:01:54.html
(Note that you'd have to use 24 hour format)
Your problem is that some programs order your files "naturally", while others sort them alphabetically. Changing your filenames to the format I suggested avoids this whole problem altogether.
The PHP documentation on natsort highlights the difference quite well:
Standard sorting
Array
(
[3] => img1.png
[1] => img10.png
[0] => img12.png
[2] => img2.png
)
Natural order sorting
Array
(
[3] => img1.png
[2] => img2.png
[1] => img10.png
[0] => img12.png
)
You can use natsort or sort_numeric. sort_numeric will break if you ever have names with no numbers. natsort will sort the numbers "naturally." Like in this answer. This might be a way to do it without changing date structure.

Sphinx Get Word in Result through PHP API

The Sphinx PHP API returns a "matches" array after executing "Query();". It also returns a "Words" array. What I'm wondering is if there is a way that for each match in the "matches" array if it would show what word was used to give that result it's weight.
For example, my query is...
"Green Banana | Yellow Banana"
The results look something like.
[18403206462384766539] => Array
(
[weight] => 4553
[attrs] => Array
(
)
)
What I'd love to see is something more like.
[18403206462384766539] => Array
(
[weight] => 4553
[attrs] => Array
(
)
[word] => "Green Banana"
)
I want to avoid having to make two separate queries and then having to compare the weights across both result arrays to find the highest one because I plan on having a query with many hundreds or thousands of OR'd phrases.
Not really. There is however PACKEDFACTORS() - which might give you some useful information.
Its a function so can be used in the `SetSelect call.

Show array as written with rand inside

I have an array such as:
$var = array('hi','ho',rand(2,5));
What I would like to echo is the entire array, exactly as written.
Normally when you try a print_r, it shows as:
Array (
[0] => hi
[1] => ho
[2] => 3
)
But I want:
Array (
[0] => hi
[1] => ho
[2] => rand(2,5)
)
You can get this with file_get_contents, but is there any way to do so within the actual PHP file?
I don't think it's possible because when array is created, random value is assigned to element with index 2 and you cannot check how this value was created.
I don't think it's possible, since the rand is already evaluated as soon as you set the array to some variable.
A workaround would be the hold the expression as a string and then eval it when you need it. Like this:
$varStr = "array('hi','ho',rand(2,5))";
echo $varStr;
// when you actually need it
$var = eval($varStr);
However, this is almost never a good idea. Providing a use-case where you need this might help come up with a better solution.

How to make GET parameters not prone to overriding?

Let's say I have an address http://example.org/articles/children/title. Now, mod_rewrite translates it into http://example.org?type=article&category=children&id=title.
Now, most users only read the first part, ignoring anything that's after question mark. And they should be safe to do so. But if someone links to me using http://example.org/articles/title?something=long_meaningless_string&type=adult&title=othertitle my app sees $type == "adult" when clicking reader believes he went to a children section.
Any safe and sure way to prevent abuse like that? It's especially problematic with well known CMS systems, where attacker knows get variable names and can use it to hit site's reputation.
One way would be to rename your keys, so that they have a [] at the end, like so:
http://example.org?type[]=article&category[]=children&id[]=title
This will result in a $_GET-Array like this:
Array
(
[type] => Array
(
[0] => article
)
[category] => Array
(
[0] => children
)
[id] => Array
(
[0] => title
)
)
If someone appends more type[]-Entries to the query-String as in http://example.org?type[]=article&category[]=children&type[]=adult, it will look like this:
Array
(
[type] => Array
(
[0] => article
[1] => adult
)
[category] => Array
(
[0] => children
)
)
So you can still get the first entry.
If you don't want to append the [] to your keys, you would have to parse the Query-String, which you can get via $_SERVER['QUERY_STRING'], yourself.
Determine a canonical URI for each page. When the page is requested, check if the URI matches the canonical one. If it doesn't, issue a 301 redirect. (e.g. like this (although that isn't PHP)).

Fields get unwantedly concatenated in Salesforce SOQL query result. Developer nearly loses it

I'm probably missing something quite basic, but I'm getting very confused (and frustrated) with the results I get from my SOQL queries to the Salesforce API.
My query:
Select Id, FirstName, LastName FROM contact
The resulting object (as rendered by print_r):
stdClass Object
(
[done] => 1
[queryLocator] =>
[records] => Array
(
[0] => stdClass Object
(
[type] => Contact
[Id] => Array
(
[0] => 0032000000cPd7uAAC
[1] => 0032000000cPd7uAAC
)
[any] => BuzzAldrin
)
[1] => stdClass Object
(
[type] => Contact
[Id] => Array
(
[0] => 0032000000cPt1zABC
[1] => 0032000000cPt1zABC
)
[any] => RonnieVanZant
)
[2] => stdClass Object
(
[type] => Contact
[Id] => Array
(
[0] => 0032000000cPb60AA
[1] => 0032000000cPb60AA
)
[any] => PollyJeanHarvey
)
)
[size] => 3
)
The first thing I don't get is why "Id" is an array. A strange quirk, but a workaround is not too hard.
The second thing bothers me endlessly more, though: I select for FirstName and LastName and what happens is they get concatenated and returned as a single string value for a field called "any". To avoid the "split it on uppercase letters" advice I already got from my colleagues, I provided an example with both a two-capital first name and a two-capital last name, and anyhow, in reality I need many more (and more formally unpredictable) fields, and they all get added to this "any" property.
Does anyone see what I'm doing wrong? Assuming it's not such a badly written API, that is?
Edit:
Said developer will now go sit in a corner for a few hours, repenting for not having checked for more recent versions of PHP Toolkit. Seems I was using 11.0, whereas there's already a version 20.0. Shame on me, shame on me indeed. Sorry for wasting your time.
The behavior you are seeing is mostly because of how PHP's SoapClient interprets the results from the API. If you call getLastResponse() on your API connection after you make the query() calls above, you'll see what the actual SOAP messages look like coming back from Salesforce.
As far as the Id array -- its not really an array, but it is listed twice per record (once for the record itself and once as a field), but PHP turns it into an array because it sees it twice. As far as the any, that's happening because PHP is not understanding the namespaced field tags correctly.
As it looks like you found, using the PHP Toolkit can help with these oddities and return sensible objects for you to work with. You might also want to consider looking at Salesforce's REST API, whose results can be directly consumed by json_decode(). For making the HTTP calls to Salesfore, you might be interested in this simple (almost standalone) REST client in a project of mine.

Categories