PHP 7.1.7 - A non-numeric value encountered - even though already checked is_numeric - operators

I've getting this non-numeric error when trying to add even though I've already checked with is_numeric. I've tried converting the $value with number_format, (float), (int). Nothing seems to work. The values are present and number from a posted multiple field.
$amount = 0;
$transaction_amount = isset($_POST['TransactionCharge']['amount']) ? $_POST['TransactionCharge']['amount']: array();
foreach($transaction_amount as $value) {
if ( is_numeric($value) ) {
$amount += number_format($value,2);
}
}
Interesting note:
$amount = array_sum($transaction_amount);
seems to work in lieu of iterating array. Is that the only way to do this in 7.1?

Simply used array_sum method to implement.

Related

bindValue and bindParam in mysqli and PDO ignore variable type

I'm having problems in understanding a part of the meaning of binding certain variable types in PDO and mysqli if the type given, in my case, seems to be meaningless. In the following code, the type bound (like i or s) gets ignored. The table row "wert_sortierung" in the database is INT(11). Regardingless if $val_int is really integer or not and if I bind it via i,s / PDO::PARAM_INT or _STR, the query always works, no break, no error or warning, that the types in the binding and database or variable itself don't fit.
<?
class PDOTest {
protected $pdo;
function __construct(){
$usr="usr";
$pwd="pwd";
$host="localhost";
$db="db";
$val_int="I'm a string";
$val_str="OP";
$querystring="SELECT wert_langtext FROM TB_wert WHERE wert_sortierung = ? AND wert_CD = ?";
try {
$db_info = "mysql:host=$host;dbname=$db"; // usually provided via require_once and during construction
$this->pdo = new PDO($db_info, $usr, $pwd);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$stmt = $this->pdo->prepare($querystring);
$stmt->bindValue(1,$val_int,PDO::PARAM_INT);
$stmt->bindValue(2,$val_str,PDO::PARAM_STR);
$stmt->execute();
$row_return = $stmt->fetchAll(PDO::FETCH_ASSOC);
$this->varprint($row_return);
$this->pdo = NULL;
}
catch (PDOException $ex) {
printf ('Es spricht:');
$this->printerror("Fehla! (" . $ex->getMessage() . ")");
$this->pdo = NULL;
exit();
}
printf("<br />-------<br />");
//Added for comparison
$mysqli = new mysqli($host, $usr, $pwd, $db);
$m_stmt = $mysqli->prepare($querystring);
$m_stmt->bind_param('is',$val_int, $val_str);
$m_stmt->execute();
$m_stmt->bind_result($row_return);
$m_stmt->fetch();
$this->varprint($row_return);
$m_stmt->close();
$mysqli->close();
}
private function printerror($txt) {
printf("<p><font color=\"#ff0000\">%s</font></p>\n",
htmlentities($txt));
}
private function varprint($var) {
echo "<br />";
echo "<pre>";
echo var_dump($var);
echo "</pre>";
}
}
new PDOTest();
?>
Please can anyone point out my error in reasoning.
It is actually Mysql's loose-typing that that deceived you.
As a matter of fact, regular Mysql queries can accept strings for the numberic values all right:
SELECT wert_langtext FROM TB_wert WHERE wert_sortierung = '1' AND wert_CD = '1';
while prepared statement just following this behavior.
However, a contrary situation is not that harmless. Addressing a string value with a number
SELECT wert_langtext FROM TB_wert WHERE wert_sortierung = 1;
will cause infinite number of warnings in case of wert_sortierung being of string type and some unexpected behavior, like matching for ALL the rows.
So, as a general advise I would suggest to always use 's' by default. The only drawback is PDO's emulated prepares and it can be easily worked around.
So, to answer your question explicitly - prepared statements just allow the same behavior as regular queries, adding nothing to it. Everything that possible with a regular query, is possible with prepared statement as well. And no, binding do not validate your data (however it should. Imn my class I test integer placeholders and throw an exception if no numeric value given)

In VTD-XML how to add new attribute into tag with existing attributes?

I'm using VTD-XML to update XML files. In this I am trying to get a flexible way of maintaining attributes on an element. So if my original element is:
<MyElement name="myName" existattr="orig" />
I'd like to be able to update it to this:
<MyElement name="myName" existattr="new" newattr="newValue" />
I'm using a Map to manage the attribute/value pairs in my code and when I update the XML I'm doing something like the following:
private XMLModifier xm = new XMLModifier();
xm.bind(vn);
for (String key : attr.keySet()) {
int i = vn.getAttrVal(key);
if (i!=-1) {
xm.updateToken(i, attr.get(key));
} else {
xm.insertAttribute(key+"='"+attr.get(key)+"'");
}
}
vn = xm.outputAndReparse();
This works for updating existing attributes, however when the attribute doesn't already exist, it hits the insert (insertAttribute) and I get "ModifyException"
com.ximpleware.ModifyException: There can be only one insert per offset
at com.ximpleware.XMLModifier.insertBytesAt(XMLModifier.java:341)
at com.ximpleware.XMLModifier.insertAttribute(XMLModifier.java:1833)
My guess is that as I'm not manipulating the offset directly this might be expected. However I can see no function to insert an an attribute at a position in the element (at end).
My suspicion is that I will need to do it at the "offset" level using something like xm.insertBytesAt(int offset, byte[] content) - as this is an area I have needed to get into yet is there a way to calculate the offset at which I can insert (just before the end of the tag)?
Of course I may be mis-using VTD in some way here - if there is a better way of achieving this then happy to be directed.
Thanks
That's an interesting limitation of the API I hadn't encountered yet. It would be great if vtd-xml-author could elaborate on technical details and why this limitation exists.
As a solution to your problem, a simple approach would be to accumulate your key-value pairs to be inserted as a String, and then to insert them in a single call after your for loop has terminated.
I've tested that this works as per your code:
private XMLModifier xm_ = new XMLModifier();
xm.bind(vn);
String insertedAttributes = "";
for (String key : attr.keySet()) {
int i = vn.getAttrVal(key);
if (i!=-1) {
xm.updateToken(i, attr.get(key));
} else {
// Store the key-values to be inserted as attributes
insertedAttributes += " " + key + "='" + attr.get(key) + "'";
}
}
if (!insertedAttributes.equals("")) {
// Insert attributes only once
xm.insertAttribute(insertedAttributes);
}
This will also work if you need to update the attributes of multiple elements, simply nest the above code in while(autoPilot.evalXPath() != -1) and be sure to set insertedAttributes = ""; at the end of each while loop.
Hope this helps.

Dynamic variable different for every Wordpress post: how to declare in loop?

I need a wordpress loop that for every post checks a meta numeric variable previously assigned to each of the taxonomies of the post and returns the sum of these meta variables.
To do so, I think I need a dynamic variable name for the total. I mean something like:
variablerelatedtopost = metataxonomy1 + metataxonomy2 + ... + metataxonomyn
echo variablerelatedtopost
How can I do that? Is it possible to generate a dynamic numeric variable via loop? and HOW can I refer to it in a general way, without adressing it with its name?
Thanks everyone! And sorry for possible English mistakes :P
EDIT: I just realized the code by Alex is not what I wanted. I need a variable which changes name at every post and which value is always = 0. Is there a solution?
can you not just add a counter to your loop like this?
//Total should start # 0 before the loop
$total = 0;
// The Query
$the_query = new WP_Query($args);
// The Loop
while ( $the_query->have_posts() ) : $the_query->the_post();
$amount = get_post_meta($post->ID, 'the_meta_data_field', true);
$total = $total + $amount;
endwhile;
//echo total
echo $total;
I found the solution to my problem: an array which increases its lenght at every cicle of the loop. I know it's simple but since I'm just a beginner it took me a while to think about it. I post the code here so maybe it can help someone (and if you find bugs or have improvements, please tell me)
//Before the loop, empty array
$totale = array();
// WP Loop
while ( $loop->have_posts() ) : $loop->the_post();
$totale[] = 0;
$indice = (count($totale)) - 1;
// $termvariable was previously set up as a term meta value
if( has_term( 'numberofterm', 'nameoftaxonomy' ) ) {
$totale[$indice] = $termvariable + $totale[$indice];
}

Getting Invalid number of parameters in Doctrine2 and Symfony Querybuilder

Here is my code
if(!$criteria){
return null;
}
$em = $this->doctrine->getEntityManagerForClass('Sample\MyBundle\Entity\Call');
$qb = $em->createQueryBuilder();
$qb->add('select', 'c')->add('from', 'Sample\MyBundle\Entity\Call c');
if($criteria->getReason() && $criteria->getReason() != null){
$qb->add('where', 'c.reason = ?1');
$qb->setParameter(1, $criteria->getReason());
}
if($criteria->getCallDate() && $criteria->getCallDate() != null){
$qb->add('where', 'c.callTime = ?2');
$qb->setParameter(2, $criteria->getCallDate());
}
if($criteria->getPage()>1){
$qb->setFirstResult(($criteria->getPage()-1) * 10)->setMaxResults(10);
}
$query = $qb->getQuery();
return $query->getResult();
I'm getting this error - Invalid parameter number: number of bound variables does not match number of tokens I googled but couldn't found a solution. Need help with this.
I even tried to put both setParameter() calls after conditional check if statements but that also give the same error. If I don't set the second parameter and remove second where condition then it works.
Oh, I guess I was making a mistake. I think I can not use multiple 'where' in 'add' function. I replaced it with $qb->andWhere('c.callTime > ?2'); and now it works fine.

CI active record, escapes & order_by datetime column

I've noticed that when ordering by a datetime column in CI with active record, it's treating the column as a string, or int.
Example:
$this->db->limit(12);
$this->db->where('subscribed',1);
$this->db->join('profiles','profiles.user_id=users.id');
$this->db->where('active',1);
$this->db->select('users.thumbUpload,users.vanity_url');
$this->db->select('users.created_on as time');
$this->db->order_by('time');
$query = $this->db->get('users');
This is where users.created_on is a datetime field. Firstly, is it because active record is rendering time escaped, or is it something else? And if it is, can I prevent the escaping on order_by somehow?
Also, stackoverflow, please stop autocorrecting 'datetime' to 'date time'. It's annoying.
Cheers!
When you set second argument as false, function wont check and escape string. Try this
$this->db->select('users.created_on as time', FALSE);
Or for you query use
$this->db->order_by('users.created_on', 'DESC'); //or ASC
And for complex queries
$this->db->query("query");
According to the signature of the method in core files of CI (currently 2.2), it does not have any option to allow to choose whether or not to escape.
// The original prototype of the order_by()
public function order_by($orderby, $direction = '') {
// Definition
}
As you see there is not argument as $escape = true in the argument list. One way to do so is to hack this core file (I normally do not suggest it, since if you upgrade CI to a newer version later, then these changes will be lost, but if you do not intend to do so, it is OK to use it).
To do so, first change the prototype as:
public function order_by($orderby, $direction = '', $escape = true) {
// Definition
}
And then check the conditions in the following parts of definition:
// Line 842
if($escape){
$part = $this->_protect_identifiers(trim($part));
}else {
$part = trim($part);
}
// Line 856
if($escape){
$orderby = $this->_protect_identifiers($orderby);
}
When you call it, to prevent the escaping:
$this->db->order_by($ORDERBY_CLAUSE, null, false);