I'm iterating through a $_POST to write each item into a text file. It's working, but despite having used 'strlen' to avoid blank lines, I'm still getting some. Can anyone tell me why? Here's my code:
$entries = "";
$filename = "test.txt";
foreach($_POST as $value) {
if( is_array( $value ) ) {
foreach( $value as $subvalue ) {
if (strlen($subvalue) > 5) {
$entries .= $subvalue . PHP_EOL;
}
}
}
}
file_put_contents($filename, $entries);
Try below code for your solution:
$entries = "";
$filename = "test.txt";
foreach($_POST as $value) {
if( is_array( $value ) ) {
foreach( $value as $subvalue ) {
if (strlen(trim($subvalue)) > 5) {
$entries .= $subvalue . PHP_EOL;
}
}
}
}
file_put_contents($filename, $entries);
Related
I need to recursively cast a PHP SimpleXMLObject to an array. The problem is that each sub element is also a PHP SimpleXMLElement.
Is this possible?
json_decode(json_encode((array) simplexml_load_string($obj)), 1);
Didn't test this one, but this seems to get it done:
function convertXmlObjToArr($obj, &$arr)
{
$children = $obj->children();
foreach ($children as $elementName => $node)
{
$nextIdx = count($arr);
$arr[$nextIdx] = array();
$arr[$nextIdx]['#name'] = strtolower((string)$elementName);
$arr[$nextIdx]['#attributes'] = array();
$attributes = $node->attributes();
foreach ($attributes as $attributeName => $attributeValue)
{
$attribName = strtolower(trim((string)$attributeName));
$attribVal = trim((string)$attributeValue);
$arr[$nextIdx]['#attributes'][$attribName] = $attribVal;
}
$text = (string)$node;
$text = trim($text);
if (strlen($text) > 0)
{
$arr[$nextIdx]['#text'] = $text;
}
$arr[$nextIdx]['#children'] = array();
convertXmlObjToArr($node, $arr[$nextIdx]['#children']);
}
return;
}
Taken from http://www.codingforums.com/showthread.php?t=87283
It is possible. This is a recursive function which prints out the tags of parent elements and the tags + contents of elements that have no more children. You can alter it to build an array:
foreach( $simpleXmlObject as $element )
{
recurse( $element );
}
function recurse( $parent )
{
echo '<' . $parent->getName() . '>' . "\n";
foreach( $parent->children() as $child )
{
if( count( $child->children() ) > 0 )
{
recurse( $child );
}
else
{
echo'<' . $child->getName() . '>';
echo iconv( 'UTF-8', 'ISO-8859-1', $child );
echo '</' . $child->getName() . '>' . "\n";
}
}
echo'</' . $parent->getName() . '>' . "\n";
}
I don't see the point since SimpleXMLObject can be threated just like arrays anyway...
But if you really need that, just check chassagnette's answer of in this thread or this post in a forum.
Depending on some troubles with CDATA, arrays etc.
(see: SimpleXMLElement to PHP Array)
I think, this would be the best solution:
public function simpleXml2ArrayWithCDATASupport($xml)
{
$array = (array)$xml;
if (count($array) === 0) {
return (string)$xml;
}
foreach ($array as $key => $value) {
if (is_object($value) && strpos(get_class($value), 'SimpleXML') > -1) {
$array[$key] = $this->simpleXml2ArrayWithCDATASupport($value);
} else if (is_array($value)) {
$array[$key] = $this->simpleXml2ArrayWithCDATASupport($value);
} else {
continue;
}
}
return $array;
}
Here my iterative (even if I don't think you will get a stack explosion by parsing data with a recursive one) implementation of a recursive cast to array. This is a more direct manner of doing it than passing through json_**decode functions:
function xml2Array(SimpleXMLElement $el): stdClass {
$ret = $el;
$stack = [&$ret];
while (count($stack) > 0) {
$cur = &$stack[count($stack) - 1];
array_splice($stack, -1);
$cur = (object) (array) $cur;
foreach ($cur as $key => $child) {
$childRef = &$cur->{$key};
if ($child instanceof SimpleXMLElement)
$stack[count($stack) - 1] = &$childRef;
elseif(is_array($child))
foreach ($childRef as $ckey => $cell) {
if ($cell instanceof SimpleXMLElement)
$stack[count($stack) - 1] = &$childRef[$ckey];
}
}
}
return $ret;
}
For those of you who have concerns about the CDATA case,
combining #ajayi-oluwaseun-emmanuel's answer with this answer worked for me:
$xml = simplexml_load_string($xml_str, 'SimpleXMLElement', LIBXML_NOCDATA);
$json = json_encode($xml);
$arr = json_decode($json,TRUE);
After parsing some html, we have an array similar to ["\u00a0","\u00a0", "foo", "\u00a0", "bar"]. I want to filter out the "\u00a0" leaving us with ["foo", "bar"]. However, when we run an equality check, we are not getting a match.
We have tried
$item != "\u00a0"
$item != "\\u00a0"
$item != ""
$item != " "
$item != chr(160)
We get the same array returned without the "\u00a0" filtered out.
function getContent($xPath) {
$query = "//div[#class='WordSection1']";
$elements = $xPath->query($query);
if (!is_null($elements)) {
$content = array();
foreach ($elements as $element){
$nodes = $element->childNodes;
foreach ($nodes as $node) {
if ($node->nodeValue != "\u00a0") {
$content[] = $node->nodeValue;
}
}
}
return $content;
}
}
Try doing this condition:
if ($node->nodeValue != "\u{00a0}") {
$content[] = $node->nodeValue;
}
Here's the sample script I used:
<?php
$words = [chr(0xC2).chr(0xA0), 'foo', chr(0xC2).chr(0xA0), 'bar'];
$output = [];
foreach ($words as $word) {
if ($word != "\u{00a0}")
$output[] = $word;
}
var_dump($output);
I have a csv with following structure:
And I need the output csv as follows:
That means taking the faetures from each column and put it in the single row.
I am using php office to fetch and write the csv. I have written the following:
if ( false === $handle = fopen('../../../3b.csv', 'r') )
throw new Exception('File open failed.');
$headers = fgetcsv($handle);
$row = '';
$row = array();
$data = '';
$data = array();
while ( false !== $fields = fgetcsv($handle) ) {
$fields = array_combine($headers, $fields);
foreach($fields as $key=>$value){
if($key!='sku'){
if($value==''){
continue;
}
}
$row[$key] = $value;
}
if(sizeof($row)==1){
unset($row['sku']);
}
$row = array_filter( $row );
$data[] = $row;
}
$data = array_filter($data);
$use_keys = ['sku','AC Rating','color','Feature','Finish','Grade','Installation Location','Installation Method','Plank Style','Size','Specie','Tile Format','Warranty','Wear Layer','Width','LifeStyle',
'Material','Style','Thickness','Appearance','PEIRating','ProtectionRating'];
foreach($data as $key=>$value){
$new_arr = [];
foreach($use_keys as $apk_item) {
$new_value = '';
if (isset($data[$key][$apk_item])) {
$new_value = str_replace(",","|",$data[$key][$apk_item]);
}
$new_arr[$apk_item] = $new_value;
}
$data[$key] = $new_arr;
}
$data = array_filter($data, 'array_filter');
$final_array = array();
foreach ($data as $features) {
$product = array('feature' => '');
foreach ($features as $key => $feature) {
if ($key == 'sku') {
$product['sku'] = $feature;
}
else {
if($feature!=''){
$product['feature'] .= $key;
$product['value'] .= $feature;
}
}
}
$final_array[] = $product;
}
$final_array = array_filter($final_array);
$table = '<table border="1" id="csvtable">
<thead><tr><th>sku</th><th>feature</th><th>value</th></tr></thead>
<tbody>';
foreach($final_array as $value){
$sku = $value["sku"];
$combinedfeature = explode(",", $value['feature']);
foreach($combinedfeature as $single){
$table .= '<tr><td width="20%">'.$sku.'</td><td width="40%">'.$single['feature'].'</td><td width="40%">'.$single['value'].'</td></tr>';
}
}
$table .= '</tbody></table>';
print_r($table);
It's giving wrong output. How can I do this? Anyone can help, please?
A much more compact method would be to read the input and write out the target file in one loop.
This code reads in each line, combines it with the header and then extracts the sku (and removes it from the details). Then loops over the remaining details, and if there is a value to output it writes the output to the result file.
As each value may also be a comma separated list, this uses explode() to split them into individual items and writes them out as separate parts...
$inputFile = "a.csv";
$outputFile = "a1.csv";
$inputHandle = fopen($inputFile, 'r');
$outputHandle = fopen($outputFile, 'w');
$headers = fgetcsv($inputHandle);
fputcsv($outputHandle, ["sku", "feature", "value" ]);
while ( false !== $fields = fgetcsv($inputHandle) ) {
$fields = array_combine($headers, $fields);
$sku = $fields['sku'];
unset($fields['sku']);
foreach ( $fields as $name => $field ) {
if (!empty(trim($field))) {
$subFields = explode(",", $field );
foreach ( $subFields as $value ) {
fputcsv($outputHandle, [$sku, $name, $value]);
}
}
}
}
fclose($inputHandle);
fclose($outputHandle);
I have multiples values in array and i want get one of name which in array.
Ex: - $val = array('test.mp4','abc.avi','xyz.3gp','abc.csv');
Now i want get the name of 'abc.csv' in $name.
Please help me to find the value which is ending with extension .csv.
I think this simple code can help
$val = array('test.mp4','abc.avi','xyz.3gp','abc.csv');
$extension = '.csv';
$name = '';
foreach ($val as $value) {
if (strpos($value, $extension) !== false) {
$name[] = $value;
}
}
print_r($name);
Try this
$list = array('test.mp4','abc.avi','xyz.3gp','abc.csv');
$name = '';
foreach ($list as $item) {
if (strrpos($item, '.csv') === 3) {
$name = $item;
}
}
echo $name;
$val = array('test.mp4', 'abc.avi', 'xyz.3gp', 'abc.csv');
foreach ($val as $value) {
$tmp = strrpos($value, ".csv");
echo substr($value, 0, $tmp );
}
foreach ($val as $value) {
$extension = explode(".", $value);
if($extension[1] == "csv"){
echo $value;
}
}
foreach ($val as $item) {
$file_extensions = explode(".", $value);
if(end($file_extensions) == 'csv'){
$allCSVFilse[] = $item;
}
}
print_r($allCSVFiles);
I making a plugin for wordpress, but i have problem with allowed memory size on my server, it is 128, they dont allow me to increase memory at run time.
my plugin have function to export user datas to csv and email to user. i getting fetal error on this wordpress, functions.php line 252
is there efficient way to optimize this below function to prevent getting error
thank you
function is_serialized( $data ) {
// if it isn't a string, it isn't serialized
if ( ! is_string( $data ) )
return false;
$data = trim( $data );
if ( 'N;' == $data )
return true;
$length = strlen( $data );
if ( $length < 4 )
return false;
if ( ':' !== $data[1] )
return false;
$lastc = $data[$length-1];
if ( ';' !== $lastc && '}' !== $lastc )
return false;
$token = $data[0];
switch ( $token ) {
case 's' :
if ( '"' !== $data[$length-2] )
return false;
case 'a' :
case 'O' :
return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
case 'b' :
case 'i' :
case 'd' :
return (bool) preg_match( "/^{$token}:[0-9.E-]+;\$/", $data );
}
return false;
}
my function - fileds are dynamic getting from admin panel
$outFile = '';
$blogusers = get_users();
// retrieve the current options
$spueIntervall = get_option('spue_intervall');
//fileds are dynamic
$spueSeperator = get_option('spue_seperator');
$spueFields = get_option('spue_fields');
// Check if the functions is already loaded
if (!function_exists('get_userdata'))
require_once (ABSPATH . 'wp-includes/pluggable.php');
// Setup the top-line of the file
foreach ($spueFields AS $fieldKey => $fieldValue)
{
if ($fieldValue == 1)
{
$outFile .= $fieldKey . $spueSeperator;
}
}
$outFile .= "\n";
// Loop to all users
foreach ($blogusers as $user)
{
// Get the userdate
$user_info = get_userdata($user->ID);
// Only output the needed data
foreach ($spueFields AS $fieldKey => $fieldValue)
{
if ($fieldValue == 1)
{
$outFile .= '"' . $user_info->{$fieldKey} . '"' . $spueSeperator;
}
}
$outFile .= "\n";
}
// Save
file_put_contents( dirname(__FILE__) . '\spue-export.csv', utf8_encode($outFile));
got it
foreach ( $blogusers as $user ) {
$data = array();
foreach ($spueFields AS $fieldKey => $fieldValue) {
if ($fieldValue == 1)
{
$value = isset( $user->{$fieldKey} ) ? $user->{$fieldKey} : '';
$value = is_array( $value ) ? serialize( $value ) : $value;
$data[] = '"' . str_replace( '"', '""', $value ) . '"';
$outFile.=implode( ',', $data ) . "\n";
}