I'm fairly new to this so I wanted to ask a question. I uploaded an excel file using html and when I try to learn how to read excel files using php, this is what I've got from IBM:
<?php
$filename = basename($_FILES["file"]["name"]);
$ext = substr($filename, strrpos($filename, '.') + 1);
function get_data($qnum, $qtype, $qname, $qtext, $atext, $pcredit, $rcounts, $r, $qcount, $cfac, $sd, $disc_inx, $disc_coef)
{
global $data;
$data[] = array('QNum' => $qnum, 'Qtype' => $qtype, 'Questionname' => $qname, 'Questiontext' => $qtext,
'Answertext' => $atext, 'PartialCredit' => $pcredit, 'RCounts' => $r, 'QCount' => $qcount,
'Correctionfacility' => $cfac, 'DiscriminationIndex' => $disc_inx, 'DiscriminationCoefficient' => $disc_coef);
}
if ($ext == "xls") {
$dom = DOMDocument::load($_FILES['file']['tmp_name']);
$rows = $dom->getElementsByTagName('Row');
$first_row = true;
foreach ($rows as $row) {
if (!$first_row) {
$qnum = "";
$qtype = "";
$qname = "";
$qtext = "";
$atext = "";
$pcredit = "";
$r = "";
$qcount = "";
$cfac = "";
$disc_inx = "";
$disc_coef = "";
$index = 1;
$cells = $row->getElementsByTagName('Cell');
foreach ($cells as $cell) {
$ind = $cell->getAttribute('Index');
if ($ind != null)
$index = $ind;
if ($index == 1)
$qnum = $cell->nodeValue;
if ($index == 2)
$qtype = $cell->nodeValue;
if ($index == 3)
$qname = $cell->nodeValue;
if ($index == 4)
$qtext = $cell->nodeValue;
if ($index == 5)
$atext = $cell->nodeValue;
if ($index == 6)
$pcredit = $cell->nodeValue;
if ($index == 7)
$r = $cell->nodeValue;
if ($index == 8)
$qcount = $cell->nodeValue;
if ($index == 9)
$cfac = $cell->nodeValue;
if ($index == 10)
$disc_inx = $cell->nodeValue;
if ($index == 11)
$disc_coef = $cell->nodeValue;
$index += 1;
}
get_data($qnum, $qtype, $qname, $qtext, $atext, $pcredit, $r, $qcount, $cfac, $disc_inx, $disc_coef);
}
$first_row = false;
}
}
else {
echo "Invalid file!";
}
?>
And I got a syntax error
Warning: DOMDocument::load(): Start tag expected, '<' not found in /tmp/phpwUIpyZ, line: 1 in /var/www/moodle/question/upload_file.php on line 16 Fatal error: Call to a member function getElementsByTagName() on a non-object in /var/www/moodle/question/upload_file.php on line 17.
What is the error on my code? Need help please thanks!
Excel is not an valid DOMDocument , so of course you can't use DOMDocument for it :)
I would suggest using something ready such as PHPExcelReader.
Good Luck,Shai.
As the error message say, $dom is a non-object - in other words, DOMDocument::load returned something, but not an object. There could be various reasons for that, but the most likely ones are:
file doesn't exist or not readable
file is malformed (not a valid DOM document), parsing failed
See the manual: http://php.net/manual/en/domdocument.load.php
Note also that you seem to be trying to parse an XLS file as a DOM document - that won't fly, those are completely different file formats.
Related
While printing column and row from an array it's showing blank not exporting any data
$inn_table = "";
if ($result['qualification']['dd1'] != "") {
$dd1 = explode(",", $result['qualification']['dd1']);
}
if ($result['qualification']['dd2'] != "") {
$dd2 = explode(",", $result['qualification']['dd2']);
}
for ($i = 0; $i < count($labels); $i++) {
if ($result['qualification']['dd1'] != "") {
echo '<pre>First';
print_r($dd1); ** //echo arrays**
for ($j = 0; $j < count($dd1); $j++) {
$temp = explode(">", $dd1[$j]);
if ($temp[0] == $labels[$i]) {
$name = explode(">", $dd1[$j]);
echo '<pre>First ';
print_r($name[1]); ** //echo names**
}
}
}
}
Here is my Array structure
and Here names which i am trying to export from Array
So i only trying to export names from that array please help
foreach($labels as $ind => $label) {
$index = $ind + 2;
$letter = range('A', 'Z')[$ind2];
$val = explode('>', $data);
$objPHPExcel->getActiveSheet()->setCellValue($letter . $index, $val[1]);
}
I'm trying to make a recursive function to get all the directories and sub directories from my ftp server in an array.
I tried a lot of functions I've found on the web. The one that works best for me is this one:
public function getAllSubDirFiles() {
$dir = array(".");
$a = count($dir);
$i = 0;
$depth = 20;
$b = 0;
while (($a != $b) && ($i < $depth)) {
$i++;
$a = count($dir);
foreach ($dir as $d) {
$ftp_dir = $d . "/";
$newdir = ftp_nlist($this->connectionId, $ftp_dir);
foreach ($newdir as $key => $x) {
if ((strpos($x, ".")) || (strpos($x, ".") === 0)) {
unset($newdir[$key]);
} elseif (!in_array($x, $dir)) {
$dir[] = $x;
}
}
}
$b = count($dir);
}
return $dir ;
}
The problem with this function is it wont allow the directory to have a "." in it's name and every file that is located in the root directory will be considered a directory as well. So I adjusted the function and got this:
public function getAllSubDirFiles($ip, $id, $pw) {
$dir = array(".");
$a = count($dir);
$i = 0;
$depth = 20;
$b =0;
while (($a != $b) && ($i < $depth)) {
$i++;
$a = count($dir);
foreach ($dir as $d) {
$ftp_dir = $d . "/";
$newdir = ftp_nlist($this->connectionId, $ftp_dir);
foreach ($newdir as $key => $x) {
if (!is_dir('ftp://'.$id.':'.$pw.'#'.$ip.'/'.$x)) {
unset($newdir[$key]);
} elseif (!in_array($x, $dir)) {
$dir[] = $x;
}
}
}
$b = count($dir);
}
return $dir ;
}
This works pretty good but and gives the result I want. but it's so slow it's unusable.
I also tried working with ftp_rawlist but it has the same drawback of being horribly slow.
public function getAllSubDirFiles() {
$dir = array(".");
$a = count($dir);
$i = 0;
$depth = 20;
$b = 0;
while (($a != $b) && ($i < $depth)) {
$i++;
$a = count($dir);
foreach ($dir as $d) {
$ftp_dir = $d . "/";
$newdir = $this->getFtp_rawlist('/' . $ftp_dir);
foreach ($newdir as $key => $x) {
$firstChar = substr($newdir[$key][0], 0, 1);
$a = 8;
while ($a < count($newdir[$key])) {
if ($a == 8) {
$fileName = $ftp_dir . '/' . $newdir[$key][$a];
} else {
$fileName = $fileName . ' ' . $newdir[$key][$a];
}
$a++;
}
if ($firstChar != 'd') {
unset($newdir[$key]);
} elseif (!in_array($fileName, $dir)) {
$dir[] = $fileName;
}
}
}
$b = count($dir);
}
return $dir;
}
public function getFtp_rawlist($dir) {
$newArr = array();
$arr = ftp_rawlist($this->connectionId, $dir);
foreach ($arr as $value) {
$stringArr = explode(" ", $value);
$newArr[] = array_values(array_filter($stringArr));
}
return $newArr;
}
I've been stuck on this problem for the last couple of days and I'am getting desperate. If any one has any suggestion please let me know
If your server supports MLSD command and you have PHP 7.2 or newer, you can use ftp_mlsd function:
function ftp_mlsd_recursive($ftp_stream, $directory)
{
$result = [];
$files = ftp_mlsd($ftp_stream, $directory);
if ($files === false)
{
die("Cannot list $directory");
}
foreach ($files as $file)
{
$name = $file["name"];
$filepath = $directory . "/" . $name;
if (($file["type"] == "cdir") || ($file["type"] == "pdir"))
{
// noop
}
else if ($file["type"] == "dir")
{
$result = array_merge($result, ftp_mlsd_recursive($ftp_stream, $filepath));
}
else
{
$result[] = $filepath;
}
}
return $result;
}
If you do not have PHP 7.2, you can try to implement the MLSD command on your own. For a start, see user comment of the ftp_rawlist command:
https://www.php.net/manual/en/function.ftp-rawlist.php#101071
If you cannot use MLSD, you will particularly have problems telling if an entry is a file or folder. While you can use the ftp_size trick, calling ftp_size for each entry can take ages.
But if you need to work against one specific FTP server only, you can use ftp_rawlist to retrieve a file listing in a platform-specific format and parse that.
The following code assumes a common *nix format.
function ftp_nlst_recursive($ftp_stream, $directory)
{
$result = [];
$lines = ftp_rawlist($ftp_stream, $directory);
if ($lines === false)
{
die("Cannot list $directory");
}
foreach ($lines as $line)
{
$tokens = preg_split("/\s+/", $line, 9);
$name = $tokens[8];
$type = $tokens[0][0];
$filepath = $directory . "/" . $name;
if ($type == 'd')
{
$result = array_merge($result, ftp_nlst_recursive($ftp_stream, $filepath));
}
else
{
$result[] = $filepath;
}
}
return $result;
}
For DOS format, see: Get directory structure from FTP using PHP.
I've build an OOP FTP Client library that's can help you on this a lot, using just this code you can retrieve a list of only the directories with addition useful information like (chmod, last modified time, size ...).
The code :
// Connection
$connection = new FtpConnection("localhost", "foo", "12345");
$connection->open();
// FtpConfig
$config = new FtpConfig($connection);
$config->setPassive(true);
$client = new FtpClient($connection);
$allFolders =
// directory, recursive, filter
$client->listDirectoryDetails('/', true, FtpClient::DIR_TYPE);
// Do whatever you want with the folders
This code a variation of Martin Prikryl one. It is slower but do not have any failures with whitespaces. Use this code only if you have any problems with the code above.
function ftp_list_files_recursive($ftp_stream, $path){
$lines = ftp_nlist($ftp_stream, $path);
$result = array();
foreach ($lines as $line) {
if (ftp_size($ftp_stream, $line) == -1) {
$result = array_merge($result, ftp_list_files_recursive($ftp_stream, $line));
}
else{
$result[] = $line;
}
}
return $result;
}
I have text file
name,name1
willhaveishere1
name,name2
willhaveishere2
name,name3
willhaveishere3
i want read it and return like that
$nn = name1
$ss = willhaveishere1
with my code i get only name1
my code is
$file1 = "file.txt";
$file = file($file1);
$count = count($file);
if($count > 0) {
$i = 1;
foreach($file as $row) {
$n = strstr($row, 'name,');
$cc = array("name,");
$dd = array("");
$nn = str_replace($cc, $dd, $n);
echo $nn;
$i++; } }
This is probably what you need
if($count > 0) {
foreach($file as $row) {
$pos = strpos($row, ',');
if($pos !== false){
echo substr($row, $pos + 1);
$nn[] = substr($row, $pos + 1);
} else {
echo $row;
$ss[] = $row;
}
}
}
EDIT
Yes, just loop through, but make sure both $nn and $ss has same count, which is depending on your file.
Also Note: mysql_* functions has been deprecated, so please use mysqli or PDO instead
$count = count($nn);
for($i=0; $i < $count; $i++){
$sql = "INSERT INTO users(name, line) VALUES('$nn[$i]', '$ss[$i]')"; mysql_query($sql);
}
EDIT 2
try this example:
$file = array(
0 => 'name,name1',
1 => 'willhaveishere1',
2 => 'name,name2',
3 => 'willhaveishere2',
4 => 'name,name3',
5 => 'willhaveishere3'
);
$count = count($file);
if($count > 0) {
foreach($file as $row) {
$pos = strpos($row, ',');
if($pos !== false){
$nn[] = substr($row, $pos + 1);
} else {
$ss[] = $row;
}
}
}
echo '<pre>';
$count = count($nn);
for($i=0; $i < $count; $i++){
$sql = "INSERT INTO users(name, line) VALUES('$nn[$i]', '$ss[$i]');";
echo $sql.PHP_EOL;
}
You can try this straightforward method:
if($fh = fopen("file.txt","r")){
$nameBefore = false;
//loop through every line of your file
while (!feof($fh)){
$line = fgets($fh);
//check if the name was detected in previous line
if ($nameBefore !== false)
{
//you have the set of name and line, do what you want
echo $nameBefore . ': ' . $line . '<br />';
$nameBefore = false;
}
else
{
//see if the line is made of two coma separated segments and the first one is 'name'
//Remember the name for the next line
$parts = explode(',', $line);
if (count($parts) == 2 && $parts[0] == 'name')
$nameBefore = $parts[1];
}
}
fclose($fh);
}
One option is to use strpos to find the first occurrence of the character in the line, and if found remove everything from the line before that position. This way you are left with only the part of the line you are interested in.
Code:
$character = ',';
$fileHandle = fopen('file.txt', 'r');
while (!feof($fileHandle)) {
// Retrieve the line from the file
$line = fgets($fileHandle);
// If the line contains the character
// Remove everything before the character
$charPos = strpos($line, $character);
if ($charPos !== false) {
$line = substr($line, $charPos + 1);
}
// Do something with the remainder of the line
echo $line . PHP_EOL;
}
fclose($fileHandle);
Output:
name1
willhaveishere1
name2
willhaveishere2
name3
willhaveishere3
If you wish to retrieve the following line, simply do another retrieve line call in your loop:
while (!feof($fileHandle)) {
// Retrieve two lines in one loop iteration
$lineOne = fgets($fileHandle);
$lineTwo = fgets($fileHandle);
}
Making sure to only apply the comma replace part on the first line. This can lead to problems though if your data is... inconsistent.
Hope this helps.
I want to upload an Excel file into a MySQL table without using PDO, but just with a simple MySQL connection.
I want to load the Excel file using DOMDocument::load but can't get it to work.
Here's what I've tried so far:
mysql_connection("localhost", "root", "");
mysql_select_db("excel");
function add_data($abc, $pqr, $xyz) {
$str = "INSERT INTO excel(abc, pqr, xyz) VALUES('$abc', '$pqr', '$xyz')";
$qry = mysql_query($str);
}
if (isset($_FILES['file'])) {
$dom = DOMDocument::load($_FILES['file']['tmp_name']);
$rows = $dom->getElementsByTagName('Row');
$first_row = true;
foreach ($rows as $row) {
if (!$first_row) {
$abc = "";
$pqr = "";
$xyz = "";
$index = 1;
$cells = $row->getElementsByTagName('Cell');
foreach ($cells as $cell) {
$ind = $cell->getAttribute('Index');
if ($ind != null)
$index = $ind;
if ($index == 1)
$abc = $cell->nodeValue;
if ($index == 2)
$pqr = $cell->nodeValue;
if ($index == 3)
$xyz = $cell->nodeValue;
$index += 1;
}
add_data($abc, $pqr, $xyz);
}
$first_row = false;
}
}
hey guys im trying to get the even indexes of a string from the db then save them in a variable then echo. but my codes seems doesnt work. please help. here it is
require_once('DBconnect.php');
$school_id = '1';
$section_id = '39';
$select_pk = "SELECT * FROM section
WHERE school_id = '$school_id'
AND section_id = '$section_id'";
$query = mysql_query($select_pk) or die (mysql_error());
while ($row = mysql_fetch_assoc($query)) {
$public_key = $row['public_key'];
}
if ($public_key) {
$leng_public_key = strlen($public_key);
$priv_key_extract = "";
$array_pki = array();
for ($i=0; $i <=$leng_public_key-1 ; $i++) {
array_push($array_pki,$public_key[$i]);
}
foreach ($array_pki as $key => $value) {
if($key % 2 == 0) {
$priv_key_extract += $public_key[$key];
} else {
$priv_key_extract ="haiiizzz";
}
}
}
echo $priv_key_extract;
as you can see im trying to use modulo 2 to see if the index is even.
I have updated your code as below, it will work now :
<?php
$public_key = 'A0L8V1I5N9';
if ($public_key) {
$leng_public_key = strlen($public_key);
$priv_key_extract = "";
$array_pki = array();
for ($i=0; $i <=$leng_public_key-1 ; $i++) {
array_push($array_pki,$public_key[$i]);
}
foreach ($array_pki as $key => $value) {
//Changed condition below $key % 2 ==0 => replaced with $key % 2 == 1
if($key % 2 == 1) {
// Changed concatenation operator , += replaced with .=
$priv_key_extract .= $public_key[$key];
} /*else {
//Commented this as it is getting overwritten
$priv_key_extract ="haiiizzz";
}*/
}
}
echo $priv_key_extract;
?>
Try this function
function extractKey($key) {
if (empty($key) || !is_string($key)) return '';
$pkey = '';
for ($i=0;$i<strlen($key);$i++) {
if ($i % 2 == 0) {
$pkey .= $key[$i];
}
}
return $pkey;
}
echo extractKey('12345678'); # => 1357