Grabbing hidden inputs as a string (Using PHP Simple HTML DOM Parser) - php

So I have a form that has 4 inputs, 2 text, 2 hidden. I've grabbed the two text input values from the name, which are (get_me_two, get_me_three) and I've also grabbed the form action which is (get_me.php). What I'm looking to do now is grab the 2 hidden inputs, but not the values. I want to grab the inputs themselves.
E.G: Here's my form:
<form action="get_me.php" method="post">
<input type="text" name="get_me_two">
<input type="text" name="get_me_three">
<input type="hidden" name="meta_required" value="from">
<input type="hidden" name="meta_forward_vars" value="0">
</form>
And what I want to grab from here is the two hidden inputs, Not the values, the complete string.
I'm not sure how to grab these using: PHP Simple HTML DOM Parser, if anybody knows a way that would be great, if not, if there's an alternative that also would be great. Once I've grabbed these I plan on passing the 2 input values to another page with the hidden strings, and of course the form action.
Also, if anybody is interested here's my full code, which includes the simple html dom functionality.
<?php
include("simple_html_dom.php");
// Create DOM from URL or file
$html = file_get_html('form_show.php');
$html->load('
<form action="get_me.php" method="post">
<input type="text" name="get_me_two">
<input type="text" name="get_me_three">
<input type="hidden" name="meta_required" value="from">
<input type="hidden" name="meta_forward_vars" value="0">
</form>');
// Get the form action
foreach($html->find('form') as $element)
echo $element->action . '<br>';
// Get the input name
foreach($html->find('input') as $element)
echo $element->name . '<br>';
?>
So, the end result would grab the 3 values, and then the 2 hidden inputs (full strings). Help would be much appreciated as It's driving me a little mad trying to get this done.

I don't use the SimpleDom (I always go whole-hog and use DOMDocument), but couldn't you do something like ->find('input[#type=hidden]')?
If the SimpleDOM doesn't allow that sort of selector, you could simply loop over the ->find('input') results and pick out the hidden ones by comparing the attributes yourself.

If you use DomDocument, you could do the following:
<?php
$hidden_inputs = array();
$dom = new DOMDocument('1.0');
#$dom->loadHTMLFile('form_show.php');
// 1. get all inputs
$nodes = $dom->getElementsByTagName('input');
// 2. loop through elements
foreach($nodes as $node) {
if($node->hasAttributes()) {
foreach($node->attributes as $attribute) {
if($attribute->nodeName == 'type' && $attribute->nodeValue == 'hidden') {
$hidden_inputs[] = $node;
}
}
}
} unset($node);
// 3. loop through hidden inputs and print HTML
foreach($hidden_inputs as $node) {
echo "<pre>" . htmlspecialchars($dom->saveHTML($node)) . "</pre>";
} unset($node);
?>

Related

PHP avoiding a long POST

This is more of a technique question rather than maybe code. I am having a php form with many fields (items to select). Naturally some of the items might be selected and some not. How do I know which ones are selected when i post the data from page 1 to page 2? I thought of testing each one if empty or not, but there are just too many fields and it doesn't feel at all efficient to use or code.
Thanks,
UPDATE EDIT:
I've tried the following and maybe it will get me somewhere before I carry on testing the repliers solutions...
<html>
<body>
<form name="test" id="name" action="testprocess.php" method="POST">
<input type="text" name="choices[shirt]">
<input type="text" name="choices[pants]">
<input type="text" name="choices[tie]">
<input type="text" name="choices[socks]">
<input type="submit" value="submit data" />
</form>
</body>
</html>
and then second page:
<?php
$names = $_POST['choices'];
echo "Names are: <br>";
print_r($names);
?>
This gives out the following:
Names are: Array ( [shirt] => sdjalskdjlk [pants] => lkjlkjlk [tie]
=> jlk [socks] => lkjlkjl )
Now what I am going to try to do is iterate over the array, and since the values in my case are numbers, I will just check which of the fields are > 0 given the default is 0. I hope this works...if not then I will let you know :)
I think what you're looking for is this:
<form action="submit.php" method="POST">
<input type="checkbox" name="checkboxes[]" value="this" /> This
<input type="checkbox" name="checkboxes[]" value="might" /> might
<input type="checkbox" name="checkboxes[]" value="work" /> work
<input type="submit" />
</form>
And then in submit.php, you simply write:
<?php
foreach($_POST['checkboxes'] as $value) {
echo "{$value} was checked!";
}
?>
The square brackets in the name of the checkbox elements tell PHP to put all elements with this name into the same array, in this case $_POST['checkboxes'], though you could call the checkboxes anything you like, of course.
You should post your code so we would better understand what you want to do.
But from what I understood you are making a form with check boxes. If you want to see if the check boxes are selected, you can go like this:
if(!$_POST['checkbox1'] && !$_POST['checkbox2'] && !$_POST['checkbox3'])
This looks if all the three check boxes are empty.
Just an idea:
Create a hidden input field within your form with no value. Whenever any of the forms fields is filled/selected, you add the name attribute of that field in this hidden field (Field names are saved with a comma separator).
On doing a POST, you can read this variable and only those fields present in this have been selected/filled in the form.
Hope this helps.
Try this.....
<?php
function checkvalue($val) {
if($val != "") return true;
else return false;
}
if(isset($_POST['submit'])) {
$values = array_filter(($_POST), "checkvalue");
$set_values = array_keys($values);
}
?>
In this manner you can get all the values that has been set in an array..
I'm not exactly sure to understand your intention. I assume that you have multiple form fields you'd like to part into different Web pages (e.g. a typical survey form).
If this is the case use sessions to store the different data of your forms until the "final submit button" (e.g. on the last page) has been pressed.
How do I know which ones are selected when i post the data from page 1 to page 2?
is a different question from how to avoid a large POST to PHP.
Assuming this is a table of data...
Just update everything regardless (if you've got the primary / unique keys set correctly)
Use Ajax to update individual rows as they are changed at the front end
Use Javascript to set a flag within each row when the data in that row is modified
Or store a representation of the existing data for each row as a hidden field for the row, on submission e.g.
print "<form....><table>\n";
foreach ($row as $id=>$r) {
print "<tr><td><input type='hidden' name='prev[$id]' value='"
. md5(serialize($r)) . "'>...
}
...at the receiving end...
foreach ($_POST['prev'] as $id=>$prev) {
$sent_back=array( /* the field values in the row */ );
if (md5(serialize($sent_back)) != $prev) {
// data has changed
update_record($id, $sent_back);
}
}

get id of checkbox created from loop php

How would i get the value of the checkboxes that have been selected from these checkboxes created with a loop in php:
<?php
while($rowequipment = mysql_fetch_assoc($sqlequipment)) {
echo '<input type="checkbox" name="equipment[]" value="'.$rowequipment['equipmentid'].'"/>
<input type="text" name="count[]" id="count[]" size="3" value=""/>' .
$rowequipment['description']."<br />";
}
?>
The above commenters are wrong: The name attributes for HTML form elements are of type CDATA. Thus, your code is correct. HTML definition found here.
The id attributes are useless, unless you need to operate using JavaScript over the DOM tree. In case you just want to process the control's values using PHP, just drop the ids.
In case you POSTed data, this iterates over all elements named equipment[]:
foreach( $_POST[ 'equipment' ] as checkBoxIndex => checkBoxValue ) {
echo '<br />Checkbox ' . checkBoxIndex . ' has value [' . checkBoxValue . ']';
}
Assuming you're generating these checkboxes in your PHP code and want to match those with checked = "checked" attribute later (maybe in other file).
As others mentioned, the HTML made by the code is not valid, fix it and then you can get what you want using DOM and XPath:
$html = new DOMDocument();
$html->loadHTML($yourMarkup);
$xpath = new DOMXpath($html);
$checkboxes = $xpath->query("*/input[#type='checkbox' and #checked='checked']");
if (!is_null($checkboxes)) {
foreach ($checkboxes as $checkbox) {
echo $checkbox->nodeValue;
}
}
If you want to get the checkboxes values on form post, then use $_POST['key'] which key is checkbox name attribute.

Reading attribute values from HTML

I have HTML stored in a string. The markup contains form input fields called initval and endval which are the value attribute values I need. How can I get them from this string markup?
<form id="compute">
<input type="hidden" name="initval" value="tal:00far" />
<input type="hidden" name="endval" value="utl:80er" />
</form>
Presuming that the structure is very reliably like that, try the following:
$htmlCode = "...";
$matches = array();
if (preg_match_all('/name="(initval|endval)"\s+value="([^"]+)"/', $htmlCode, $matches)) {
$formValues = array_combine($matches[1], $matches[2]);
} else {
// error
}
This assumes only whitespace between the name and value attributes, you'll need to make a small change if it differs. preg_match_all() returns an array with the whole regexp match at [0], and then the individual group matches in their corresponding locations [1] & [2], the array combine takes one as keys, one as values and puts it together so you have an associative lookup to get your results.
If I have got your question right,
In HTML
<form id="compute" action="somefile.php" method="GET">
<input type="hidden" name="initval" value="tal:00far" />
<input type="hidden" name="endval" value="utl:80er" />
<input type="submit" value="Click!">
</form>
Upon clicking submit the data is sent the the php script, where it can be read as
$initval = $_GET['initval'];
$endval =$_GET['endval'];
EDIT: It seems I have got the question wrong, Sorry. :-(
Try Using htmldomlibraries for parsing html.

array input like name="person[]" in zend form

In normal html, we could have an array field like person[]
<input name="person[]" type="text" />
<input name="person[]" type="text" />
<input name="person[]" type="text" />
As far as I know, Zend_Form doesn't have that. I read another answer that suggested it could be done using a decorator that would add the [] at the right place. This is the code for that specific question
$html = ''; // some code html
$i = 0;
foreach ($element->getMultiOptions() as $value => $label){
$html .= '<input type="checkbox" '
. 'name="'.$element->getName().'[]" '
. 'id="'$element->getName()'-'.$i.'" '
. 'value="'.$value.'" />';
$i++;
}
return $html;
This looks like a good start, but I wonder if using a decorator is enough. The values that get returned back have to be read correctly and delivered to the server, then validated on the server side. So is a decorator the wrong idea? Would a custom element make more sense here? I haven't seen a good example that shows how this can be done.
I think that ZF does not allow for creation of individual input text fields named person[], although you could do it for the whole form or a subform. However, it allows for something similar. Specifically, you could create fields named person[0], person[1], etc.
To do this, you could do the following:
$in1 = $this->createElement('text', '0');
$in2 = $this->createElement('text', '1');
$in1->setBelongsTo('person');
$in2->setBelongsTo('person');
This way you could normally attach your validators, filters, etc. to $in1 or $in2 and they would work as expected. In your action, after form validation, you could get an array of the person's input text fields as:
$values = $yourForm->getValues();
var_dump($values['person']);
Interestingly, the following will NOT work:
$in1 = $this->createElement('text', 'person[0]');
$in2 = $this->createElement('text', 'person[1]');
Hope this will help you.

How to extract value from hidden field on form

I have form (on my own blog/cms install which i want to play with a bit) with hidden value which i want to extract. Problem is that there are 2 forms on that page, each with that hidden field with value. On each form field name is the same, only hidden value differs. Something like this:
<input type="hidden" id="_hiddenname" name="_hiddenname" value="valuehere"/>
Both look the same in html source. So, to help myself i opened php file with this page, edited it and added some random words before field that i need. So now one field (the one that i don't want) is like in above code but field i need is like this:
mywordshere <input type="hidden" id="_hiddenname" name="_hiddenname" value="valuehere"/>
How do i extract value from field i need (with mywordshere before its code) if i have my page's html source in php variable (grabbed with libcurl)?
An example using DOMDocument
<?php
$html = <<<HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<body>
<input type="hidden" id="_hiddenname" name="_hiddenname" value="valuehere">
</body>
</html>
HTML;
$doc = new DOMDocument();
$doc->validateOnParse = true;
$doc->loadHTML( $html );
$node = $doc->getElementById( '_hiddenname' );
echo $node->getAttribute( 'value' );
?>
Note: your HTML string must have a DOCTYPE defined for this to work.
Assumably the two forms have different names, correct? So if you parse your scraped text with something DOM aware, you should be able to choose your input field by searching for it in its parent form.
The fact that you have two input fields named the same, and with the same id, is the real problem. The id attribute for HTML elements is supposed to be unique on a given page, and if it was, you could do this easily with a DOM parser. Example:
$dom = new domDocument;
$dom->loadHTML($html);
$dom->preserveWhiteSpace = false;
$inputs = $dom->getElementsByTagName('input');
foreach ($inputs as $i)
{
if ($i->getAttribute('id') == 'targetId') {
//do some stuff
}
}
Since you can't take that approach, and you've marked your input with a string that you can identify, I would use a combination of string functions:
$str = 'mywordshere <input type="hidden" id="_hiddenname" name="_hiddenname" value="valuehere"/>';
$pos = strpos($str,'mywordshere');
if ($pos !== false) {
$valuePos = strpos($str,'value=',$pos);
if ($valuePos !== false) {
//get text starting from the 'value=' portion of the string
$str = substr($str,$valuePos);
$arr = explode('"',$str);
//value will be in $arr[1]
echo $arr[1];
}
}
I would strongly recommend you re-work your element IDs however, and use the DOM approach.
The value will be available in either $_GET["_hiddenname"] or $_POST["_hiddenname"], depending on which method you are using. Which one you get will depend on which form is doing the submitting.
If you have two fields which are named the same within the same form, you have a bigger problem.

Categories