Simple DOM Parser PHP expecting exactly one result from CSS selector - php

Hey I have a problem with Simple DOM parser which is driving me nuts.
This works OK:
foreach($html->find('input[name=sex]') as $e)
echo $e->value;
Even if its only 1 result.
However this doesn't work:
echo $html->find('input[name=sex]')->value;
I don't want really use foreach because I expect only 1 result.
So someone could help me with second block of code?
Cheers

According to the docs, the second parameter is the index you wish to find. Set that to 0 to return the first (0th) element rather than an array of objects:
Find elements by the CSS selector. Returns the Nth element object if index is set, otherwise return an array of object.
$html->find('input[name=sex]', 0)->value;

$html->find('input[name=sex]')[0]->value;
It seems find returns an array so using index would help you.
Use the code above.

If you can use for-each on something, it is an array/collection, even if there is one element. You are asking to echo an entire array, for which which may need print_r. As another poster suggested, use a subscript.

Related

Does PHP's in_array really go through the whole array?

I stumbled over a few articles (e.g. this one) and infos that suggest PHP's in_array() goes through the whole array.
Now there is a possible duplicate of this question here: How does PHP's in_array function work? but the OP was obviously satisfied with the copy/paste of the C language function definition and no further description...
My question however is:
Does PHP's in_array() really go through the whole array?
I tried to look further and go after the ZEND_HASH_FOREACH_KEY_VAL, but then it got a bit confusing:
the C-language definition of php_search_array() ... AKA in_arary() in PHP
Codes of ZEND_HASH_FOREACH_KEY_VAL and ZEND_HASH_FOREAC
Only thing I am sure of is that since the ??iteration?? happens on the "C-level" it should be faster than "manual" foreach...
Does PHP's in_array really go through the whole array?
TLDR; No it doesn't.
The way I read the C implementation:
ZEND_HASH_FOREACH_KEY_VAL or rather ZEND_HASH_FOREACH iterates over the array data bucket with a pointer to the current element.
The element pointer is assigned to the variable entry in void php_search_array for each iteration.
When a match is found, The PHP list item itself or PHP bool is returned by the engine depending on the behavior argument given to the function.
To answer your question:
php_search_array either invokes Zend RETURN_TRUE (impl: https://github.com/php/php-src/blob/master/Zend/zend_API.h) or sets RET_VAL and performs a C return; afterwards. It both cases, C execution breaks out of the iteration of the array if a match is found.

Check entire array for single if operation

I have this code to check some input data to be sure it fits a proper format. However input_28 is a list field that is sent as an array. Is there a shortcut to check each item in the array for the filter instead of looping through each item?
I dont care what it wrong or which line does not match. I just need to know if any line does not match the filter so I can return the form with an error.
if($_POST['input_28'] != filter_var($_POST['input_28'], FILTER_VALIDATE_REGEXP,array("options"=>array("regexp"=> "/(\d\d\d\d-\d\d\d\d)|()/" )))){
If I understand correctly, you are looking for array_search(), you can use it like this
if(array_search($value, $array)){
// Do stuff
}
Note that array_search() only works if the array is NOT multi-dimensional, you can take a look on the documentation for more references and examples
Some searching on functions that #Alfonso mentioned in his answer led me to another function: preg_grep That led to this little function which worked great.
$input_28=preg_grep("/^(\d\d\d\d-\d\d\d\d)$/", $_POST['input_28'], PREG_GREP_INVERT);
if(count($input_28) > 0){
#Do Something
}
The PREG_GREP_INVERT makes it return an array of entries that do NOT match the filter. Then we count the array, if any did not match the array will have an entry. Thus greater than 0

Return Array Element without Creating Variable

I feel stupid for asking this cause it seems so basic but it's really bugging me.
I have a method that returns an array with a single element. I just want it to return the element not wrapped in an array. I tried this.
return $f->getValue()[0];
and it gives an error but if I save it to a variable, it works fine.
$v = $f->getValue();
return $v[0];
I can't figure it out....
It's available only since PHP 5.4: http://codepad.viper-7.com/VHOW0o
What you are trying to do, is called array dereferencing, and is only possible in PHP as of version 5.4 (if you scroll up a few lines in the documentation article I linked to, you'll see it mentioned).
Use reset().
<?php return reset( $f->getValue() ); ?>
Edit: reset() is probably superior to current() as it also makes sure that the internal pointer is reset, despite it not making much difference if the array only contains one element.
As far as I know since you are returning an array you only can get an array. You can instead save the array to a variable in the class (accessible by $f->myArray) and then return just the string portion. Or the other option is to do what your second example is and return the array and retrieve the string from it.
have you tried this
<?php
return array_shift(array_values($array));
?>
Get the first element of an array

Better way to get first element of returned array

I found myself using this:
$var=(string)array_shift(array_values($item->xpath($s)));
where $s is an xpath search string and the return is an array of objects that contain strings.
It works, but I'm not sure it's the best way to get the data I want.
I could use a tempvar, but I wanted to avoid that.
Any suggestions?
Careful with array_shift, as it will remove the element from the array stack, if you simply want the first value, you can use current:
$var = (string) current($item->xpath($s));
I believe this gives the same result.
$var=array_shift($item->xpath($s));
$var = $reset($item->xpath($s));
Note that this rewinds the array's internal pointer and returns the first element. The method current returns the element at the position the pointer happens to be in - it is not guaranteed to always be the first element.

php array or not array?

I don't understand... I'm doing something and when I do print_r($var); it tells me that I have an array, so naturally I think I have an array yet when I do
if(is_array($xml->searchResult->item))
it returns false
I use this array with foreach(); in documentation it says that foreach() won't work with anything else but array, so assuming that this is an array that I'm working...
plus, if I try to access it via
echo $xml->searchResult->item[3];
i will get 4th element of my array
print_r will also print objects as though they are arrays.
well, is_array() returns true if your variable is an array, otherwise, it returns false. In your case, $xml->searchResult->item seems not to be an array. What is the output for
var_dump($xml->searchResult->item)
? Another hint: You can determine the type of a variable via gettype().
is_array() returns true only for real php arrays. It is possible to create a "fake" array by using the ArrayAccess class. That is, you can use normal array semantics (such as item[3]) but it is not a real array. I suspect your $item is an object. So use
if($x instanceof ArrayAccess || is_array($x))
Instead.
plus, if I try to access it via echo $xml->searchResult->item[3]; i will get 4th element of my array
That's right, the first element is always 0 unless you specifically change it.
The manual does mention that foreach works on objects as well, and it will iterate over properties.
In your case, the situation is slightly different because I guess you're using SimpleXML, which is yet another special case. SimpleXMLElement has its own iterator, which I assume is hardcoded as it doesn't seem to implement any of SPL's Iterator interfaces.
Long story short, some objects can be used as an array, but they are not one.
Just be careful to check what has been returned by your array. You might have an object with class or stdClass which is empty and you cannot get element from it.

Categories