So, I have two files
In the first file, there is
text:hash
In the other file there is
hash:pass
I wrote some code to match the hash and then print the text (So when ran, I'd get an output of text:pass)
It works fine and it finds all the information, however sometimes it will skip certain ones and just not find anything. (If I go and do it by hand the data is there) So I'm not sure why it will find most of them but not all. Anyway I'm hoping someone can help, the code is below:
<?php
$emailhash = file('emailhash.txt');
$hashpass = file('hashpass.txt');
$list = '';
foreach($emailhash as $data) {
$data = str_replace("\r\n",'', $data);
$array_emailhash = explode(":", $data);
$email = $array_emailhash[0];
$hash = $array_emailhash[1];
foreach($hashpass as $data2) {
$data2 = str_replace("\r\n",'', $data2);
$array_hashpass = explode(":", $data2);
$hash2 = $array_hashpass[0];
$pass = $array_hashpass[1];
if($hash2 == $hash)
$list .= $email.':'.$pass."\r\n";
}
}
file_put_contents('emailpass.txt', $list);
You need to iterate your iterator, for example using multipleIterator, since you reads the entire file into an array, do like this.
$iterator = new MultipleIterator();
$iterator->attachIterator( new ArrayIterator( $emailhash ));
$iterator->attachIterator( new ArrayIterator( $hashpass ));
foreach( $iterator as $value ) {
list($keys1, $keys2) = $iterator->key();
list($value1, $value2) = $value;
}
Take a look at this -> http://br1.php.net/MultipleIterator
This algorithm is very inefficient. try to do this like that
$emailhash = file('emailhash.txt');
$hashpass = file('hashpass.txt');
$hashToEmail = array();
$list = '';
foreach($emailhash as $data) {
$data = str_replace("\r\n",'', $data);
$array_emailhash = explode(":", $data);
$email = $array_emailhash[0];
$hash = $array_emailhash[1];
$hashToEmail[$hash] = $email;
}
foreach($hashpass as $data2) {
$data2 = str_replace("\r\n",'', $data2);
$array_hashpass = explode(":", $data2);
$hash2 = $array_hashpass[0];
$pass = $array_hashpass[1];
if (array_key_exists($hash2, $hashToEmail)) {
$list .= $hashToEmail[$hash2].':'.$pass."\r\n";
} else {
//what to do if you don't have that password hash
}
}
Your design has Big O complexity of n^2 [for 1000 rows it will take 1 000 000 iterations]
the one without nested foreach has a complexity of 2n. [it will take 2000 iterations]. Try to find a solution for that :)
Anyway in both places there is a issue, because you can have a hash collisions (for two different emails you can have the same hash, then for all emails you will print out same (probably wrong password).
Related
I'm tring to get all content from this xml: https://api.eveonline.com/eve/SkillTree.xml.aspx
To save it on a MySQL DB.
But there are some data missing...
Could any1 that understand PHP, Array() and XML help me, please?
This is my code to get the content:
<?php
$filename = 'https://api.eveonline.com/eve/SkillTree.xml.aspx';
$xmlbalance = simplexml_load_file($filename);
$skills = array();
for ($x=0;$x<sizeOf($xmlbalance->result->rowset->row);$x++) {
$groupName = $xmlbalance->result->rowset->row[$x]->attributes()->groupName;
$groupID = $xmlbalance->result->rowset->row[$x]->attributes()->groupID;
for ($y=0;$y<sizeOf($xmlbalance->result->rowset->row[$x]->rowset->row);$y++) {
$skills[$x]["skillID"] = "".$xmlbalance->result->rowset->row[$x]->rowset->row[$y]->attributes()->typeID;
$skills[$x]["skillName"] = "".$xmlbalance->result->rowset->row[$x]->rowset->row[$y]->attributes()->typeName;
$skills[$x]["skillDesc"] = "".$xmlbalance->result->rowset->row[$x]->rowset->row[$y]->description;
$skills[$x]["skillRank"] = "".$xmlbalance->result->rowset->row[$x]->rowset->row[$y]->rank;
$skills[$x]["skillPrimaryAtr"] = "".$xmlbalance->result->rowset->row[$x]->rowset->row[$y]->requiredAttributes->primaryAttribute;
$skills[$x]["skillSecondAtr"] = "".$xmlbalance->result->rowset->row[$x]->rowset->row[$y]->requiredAttributes->secondaryAttribute;
$o = 0;
for ($z=0;$z<sizeOf($xmlbalance->result->rowset->row[$x]->rowset->row[$y]->rowset->row);$z++) {
if ($xmlbalance->result->rowset->row[$x]->rowset->row[$y]->rowset->attributes()->name == "requiredSkills") {
$skills[$x]["requiredSkills"]["".$xmlbalance->result->rowset->row[$x]->rowset->row[$y]->rowset->row[$z]->attributes()->typeID] = "".$xmlbalance->result->rowset->row[$x]->rowset->row[$y]->rowset->row[$z]->attributes()->skillLevel;
$o++;
}
}
}
}
echo '<pre>'; print_r($skills); echo '</pre>';
?>
If you go to the original XML (link), at line 452, you will see:
<row groupName="Spaceship Command" groupID="257">
And that isn't show in my array (link)...
That is one thing that i found that is missing...
I think that probally have more content that is missing too..
Why? How to fix it, please?
Thank you!!!
You will only get a total of sizeof($xmlbalance->result->rowset->row) records. Because, in your 2nd for loop, you are basically storing your result in the same array element that is $skills[$x].
Try this (I also higly encourage you to be as lazy as you can when you write code - by lazy I mean, avoid repeating / rewriting the same code over and over if possible) :
$filename = 'https://api.eveonline.com/eve/SkillTree.xml.aspx';
$xmlbalance = simplexml_load_file($filename);
$skills = array();
foreach ($xmlbalance->result->rowset->row as $row)
{
$groupName = $row->attributes()->groupName;
$groupID = $row->attributes()->groupID;
foreach ($row->rowset->row as $subRow)
{
$skill['skillID'] = (string) $subRow->attributes()->typeID;
$skill['skillName'] = (string) $subRow->attributes()->typeName;
$skill['skillDesc'] = (string) $subRow->description;
$skill['skillRank'] = (string) $subRow->rank;
$skill['skillPrimaryAtr'] = (string) $subRow->requiredAttributes->primaryAttribute;
$skill['skillSecondAtr'] = (string) $subRow->requiredAttributes->secondaryAttribute;
foreach ($subRow->rowset as $subSubRowset)
{
if ($subSubRowset->attributes()->name == 'requiredSkills')
{
foreach ($subSubRowset->row as $requiredSkill)
{
$skill['requiredSkills'][(string) $requiredSkill->attributes()->typeID] = (string) $requiredSkill['skillLevel'];
}
}
}
$skills[] = $skill;
}
}
print_r($skills);
I'm working on a project in which I pull various statistics about the NHL and inserting them into an SQL table. Presently, I'm working on the scraping phase, and have found an XML parser that I've implemented, but I cannot for the life of me figure out how to pull information from it. The table can be found here -> http://www.tsn.ca/datafiles/XML/NHL/standings.xml.
The parser supposedly generates a multi-dimmensional array, and I'm simply trying to pull all the stats from the "info-teams" section, but I have no idea how to pull that information from the array. How would I go about pulling the number of wins Montreal has? (Solely as an example for the rest of the stats)
This is what the page currently looks like -> http://mattegener.me/school/standings.php
here's the code:
<?php
$strYourXML = "http://www.tsn.ca/datafiles/XML/NHL/standings.xml";
$fh = fopen($strYourXML, 'r');
$dummy = fgets($fh);
$contents = '';
while ($line = fgets($fh)) $contents.=$line;
fclose($fh);
$objXML = new xml2Array();
$arrOutput = $objXML->parse($contents);
print_r($arrOutput[0]); //This print outs the array.
class xml2Array {
var $arrOutput = array();
var $resParser;
var $strXmlData;
function parse($strInputXML) {
$this->resParser = xml_parser_create ();
xml_set_object($this->resParser,$this);
xml_set_element_handler($this->resParser, "tagOpen", "tagClosed");
xml_set_character_data_handler($this->resParser, "tagData");
$this->strXmlData = xml_parse($this->resParser,$strInputXML );
if(!$this->strXmlData) {
die(sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($this->resParser)),
xml_get_current_line_number($this->resParser)));
}
xml_parser_free($this->resParser);
return $this->arrOutput;
}
function tagOpen($parser, $name, $attrs) {
$tag=array("name"=>$name,"attrs"=>$attrs);
array_push($this->arrOutput,$tag);
}
function tagData($parser, $tagData) {
if(trim($tagData)) {
if(isset($this->arrOutput[count($this->arrOutput)-1]['tagData'])) {
$this->arrOutput[count($this->arrOutput)-1]['tagData'] .= $tagData;
}
else {
$this->arrOutput[count($this->arrOutput)-1]['tagData'] = $tagData;
}
}
}
function tagClosed($parser, $name) {
$this->arrOutput[count($this->arrOutput)-2]['children'][] = $this->arrOutput[count($this- >arrOutput)-1];
array_pop($this->arrOutput);
}
}
?>
add this search function to your class and play with this code
$objXML = new xml2Array();
$arrOutput = $objXML->parse($contents);
// first param is always 0
// second is 'children' unless you need info like last updated date
// third is which statistics category you want for example
// 6 => the array you want that has wins and losses
print_r($arrOutput[0]['children'][6]);
//using the search function if key NAME is Montreal in the whole array
//result will be montreals array
$search_result = $objXML->search($arrOutput, 'NAME', 'Montreal');
//first param is always 0
//second is key name
echo $search_result[0]['WINS'];
function search($array, $key, $value)
{
$results = array();
if (is_array($array))
{
if (isset($array[$key]) && $array[$key] == $value)
$results[] = $array;
foreach ($array as $subarray)
$results = array_merge($results, $this->search($subarray, $key, $value));
}
return $results;
}
Beware
this search function is case sensitive it needs modifications like match to
a percentage the key or value changing capital M in montreal to lowercase will be empty
Here is the code I sent you working in action. Pulling the data from the same link you are using also
http://sjsharktank.com/standings.php
I have actually used the same exact XML file for my own school project. I used DOM Document. The foreach loop would get the value of each attribute of team-standing and store the values. The code will clear the contents of the table standings and then re-insert the data. I guess you could do an update statement, but this assumes you never did any data entry into the table.
try {
$db = new PDO('sqlite:../../SharksDB/SharksDB');
$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
} catch (Exception $e) {
echo "Error: Could not connect to database. Please try again later.";
exit;
}
$query = "DELETE FROM standings";
$result = $db->query($query);
$xmlDoc = new DOMDocument();
$xmlDoc->load('http://www.tsn.ca/datafiles/XML/NHL/standings.xml');
$searchNode = $xmlDoc->getElementsByTagName( "team-standing" );
foreach ($searchNode as $searchNode) {
$teamID = $searchNode->getAttribute('id');
$name = $searchNode->getAttribute('name');
$wins = $searchNode->getAttribute('wins');
$losses = $searchNode->getAttribute('losses');
$ot = $searchNode->getAttribute('overtime');
$points = $searchNode->getAttribute('points');
$goalsFor = $searchNode->getAttribute('goalsFor');
$goalsAgainst = $searchNode->getAttribute('goalsAgainst');
$confID = $searchNode->getAttribute('conf-id');
$divID = $searchNode->getAttribute('division-id');
$query = "INSERT INTO standings ('teamid','confid','divid','name','wins','losses','otl','pts','gf','ga')
VALUES ('$teamID','$confID','$divID','$name','$wins','$losses','$ot','$points','$goalsFor','$goalsAgainst')";
$result= $db->query($query);
}
I'm trying to store a string in an array, but it doesn't save the array:
<?php
session_start();
$username = $_POST["username"];
$password = $_POST["password"];
$users = array();
$passes = array();
/*if (isset($_SESSION['users'])) {
$users = unserialize($_SESSION['users']);
}
if (isset($_SESSION['passes'])) {
$passes = unserialize($_SESSION['passes']);
}*/
if (isset($_POST['button'])) {
$login_successful = false;
for ($i = 0; $i < count($_SESSION['user']); $i++) {
if ($username === $_SESSION['user'][$i] && $password === $_SESSION['pass'][$i]) {
echo "<p style=\"font-family: Open Sans\">Logged in as " .$users[$i] ."</p>";
$login_successful = true;
break; // no need to continue the loop here, so we break out of it
}
}
if (!$login_successful) {
echo "<p style=\"font-family: Open Sans\">Login Failed</p>";
}
}
else if (isset($_POST['register'])) {
$users = array_push($users, $username);
$passes = array_push($passes, $password);
$_SESSION['user'] = serialize($users);
$_SESSION['pass'] = serialize($passes);
echo "Made your account successfully! Go back to login";
}
else if (isset($_POST['userlist'])) {
$users = unserialize($_SESSION['users']);
$passes = unserialize($_SESSION['passes']);
for ($i = 0; $i < count($users); $i++) {
echo $user[$i];
echo $passes[$i];
}
}
?>
It doesn't save the array, it changes it only for the current page it was called on and then the array goes back to nothing.
Thanks in advance
You seem to have a huge misunderstanding of how PHP works. Each time a php script runs, it's like the first very first time it has ever ran. So, your array will be removed from memory when the script finishes.
However, if you want to carry data between requests, you can try a session.
session_start();//important
//YOUR EXISTING ARRAY
$array = array("element", "element 2", "element 3");
//ADD YOUR NEW ELEMENT TO THE ARRAY
$array = array_push( $array, "NEW ELEMENT" );
//store the new serialized (converted to string) array
$_SESSION['my_array'] = serialize( $array );
if ( isset($_SESSION['my_array']) ) {
//grab the serialized (string version) of the array, and convert it back to an array
$my_array = unserialize( $_SESSION['my_array'] ); //holds [0] => "el1", [1] => "el2"
}
Read more about sessions from the PHP manual.
You can also try cookies or storing the array into a database. Just know that cookies are stored on the user's computer, and sessions are stored on the server.
you can use array_push like this : $user=array_push($user,$username);
That's all!
let's do some improvement on Ryan Smith's solution to make it simpler
session_start();
$_SESSION['users'][] = 'Hello';
var_dump($_SESSION['users']);
// if you wanna use $users,
/*
if(isset($_SESSION['users'])) {
$users = unserialize($_SESSION['users']);
}
*/
I need a user to be able to enter data into a textarea in the following format.
name,email#email.com
name,email#email.com
name,email#email.com
The information would then be sent to the mysql database. My issue is that I want to place the proper name into the first column and the proper email into the second column. Then, when I encounter a line break I would like it to start a new row.
Can anyone help with this? Thanks!
As others have said you can use explode to get the results into an array however, the problem with this approach is there is no guarantee the user will enter the information in the correct order.
What I would do is this. It's still not fool proof (And using separate inputs would be better) but it's better.
<?php
$textareastring = $_POST['textareaname'];
$array = explode("\n",$textareastring );
foreach($array as $value) {
$data = explode(',',$value);
if (strpos($data[1], '#'))
{
$name = $data[0];
$email = $data[1];
}else{
$name = $data[1];
$email = $data[0];
}
}
?>
I would use explode() to separate the different lines and then the fields. Like that:
$lines = explode("\n", $_POST['textarea']);
foreach($lines as $line) {
$fields = explode(',', $line);
$name = $fields[0];
$email = $fields[1];
// DO YOUR MYSQL STUFF HERE
}
There might be better ways out there, but that would work for you.
<?php
$textareastring = $_POST['textareaname'];
$array = explode("\n",$textareastring );
foreach($array as $value) {
$data = explode(',',$value);
$name = $data[0];
$email = $data[1];
//Your mysql query goes here
}
?>
I'm trying to build a page which queries my database and then formats output so another webservice/page can access the data.
Ideally I wanted to explore having the data in JSON format, but that is not working. The other problem I have which is more major than the JSON not working is, if I have 3 records in $reportsResult, only the last one is displayed.
Anyone with some help please. Oh do I also need to print_r for the external webpage to retrieve the data or is there a better way?
class Pupil {
public $FirstName = "";
public $LastName = "";
}
foreach($reportsResult->getRecords() as $reportRecord) {
$Pupil = new Pupil();
$Pupil->FirstName = $reportRecord->getField('FName');
$Pupil->LastName = $reportRecord->getField('SName');
}
json_encode($Pupil);
OK managed to figure out how how to get all records from the loop, but its still not displaying in json format when I do a print_r - am I missing something?
$AllPupils = array();
foreach($reportsResult->getRecords() as $reportRecord)
{
$Pupil = new Pupil();
$Pupil->FamID = $reportRecord->getField('FName');
$Pupil->ChildName = $reportRecord->getField('SName');
array_push($AllPupils, $Pupil);
}
json_encode($AllPupils);
Everytime your foreach loop starts again, it will override your $Pupil variable.
Try an array instead:
$Pupil = array()
$i = 0;
foreach($reportsResult->getRecords() as $reportRecord) {
$Pupil[$i] = new Pupil();
$Pupil[$i]->FirstName = $reportRecord->getField('FName');
$Pupil[$i]->LastName = $reportRecord->getField('SName');
$i++;
}
echo json_encode($Pupil);
Edit: mikemackintosh's solution should also work and could be a little bit faster (depending on the size of your foreach loop).
To display the results you need to echo your data (not only json_encode).
You will probably run into issues since json_encode wont handle the whole object. for that, you may want to serialize the $Pupil object.
Something like below may work for you though. It will assign the values to a returned array, which will allow json_encode to execute gracefully:
class Pupil {
public $FirstName = "";
public $LastName = "";
public function getAttr(){
return array("FirstName" => $this->FirstName, "LastName" => $this->LastName);
}
}
$json = array();
foreach($reportsResult->getRecords() as $reportRecord) {
$Pupil = new Pupil();
$Pupil->FirstName = $reportRecord->getField('FName');
$Pupil->LastName = $reportRecord->getField('SName');
$json[] = $Pupil->getAttr();
}
echo json_encode($json);
I am not sure why you have that class defined, but you know what in your for each have something like
foreach ($reportsResult->getRecords() as $key => $record) {
$data[$key]['firstname'] = $record->getField('Fname');
$data[$key]['lastname'] = $record->getField('Sname');
}
And then you can check the final array using print_r
and while output you can simply do a print json_encode($data) and it will give you a json string of all the items in the data array.
In php (at least), json_encode takes an array as parameter.
Therefore you should add a constructor to your class
function __construct($first, $last)
{
this.$FirstName = $first;
this.$LastName = $last;
}
and one for getting the full name as an array, ready to be jsoned
function getNameArray()
{
$nameArray = array();
$nameArray['firstName'] = this.$FirstName;
$nameArray['lastName'] = this.$LastName;
return $nameArray;
}
then in that foreach you build another array with all the pupils
$pupils = array();
foreach (bla bla)
{
$first = $reportRecord->getField('FName');
$last = $reportRecord->getField('SName');
$Pupil = new Pupil($first, $last);
array_push($pupils, $pupil.getNameArray());
}
finally, you have everything preped up
json_encode($pupils);
I'm sure there's other ways to debug your stuff, I use print_r mainly also.