Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


kicken last won the day on May 1

kicken had the most liked content!

1 Follower

About kicken

Contact Methods

  • Website URL

Profile Information

  • Gender
  • Location
    Bonita, FL
  • Age

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

kicken's Achievements

Prolific Member

Prolific Member (5/5)




Community Answers

  1. A remote server will not have access to your local file system, so no you cannot have your remote PHP script copy files to your local system.
  2. I started with PHP somewhere around 2000 or 2001, don't remember exactly when. I was still in high school at that time so I don't know if I'd qualify as an "old fart" though.
  3. This is pointless the way you have it: $file=basename($_GET['f']); $file=__DIR__.'/download/'.$file; You're still using $_GET['f'] when you call the function below. You need to change it to use $file. if (!file_exists($file)) { die; } else { //... } While it's fine to have it, you don't need the else block here since the if branch will cause the script to end. The code is cleaner looking without it IMO.
  4. No, as noted in my reply: The XModem protocol for sending wouldn't be too hard to implement, just as receive wasn't. What would be more difficult is dealing with the serial connection to your device. You'd likely have to create a script that can connect to your device and issue whatever commands are necessary to get it ready to receive. That would be a more complex task and likely have to be tailor made to your device. I don't think it's impossible to do, PHP is capable of dealing with serial connections. I simply don't currently have any xmodem capable serial devices to mess with (did the receive bit over ssh), nor do I really have much free time to continue messing with it.
  5. Flip your if statement so that it checks if the file does not exist and if that is true, exit. if (!file_exists($l_filename)){ exit; } //... While testing, it's easier if you use text files, then you can easily see the results and any potential errors directly in the browser. Once you have it working with the text files you can try binary files. As mentioned before, you also need to validate the filename selected or someone could use your code to download any of your files, not just the ones you intend. If you want to only allow the files within the folder to be downloaded, then you could use basename so the user only inputs a file name and not a directory, then combine that with __DIR__ to make a full path. $file=basename($_GET['f']); $file=__DIR__.'/'.$file;
  6. I was interested since I've actually used Xmodem a couple times in the last year. Implementing the protocol was easy enough, figuring how terminal settings to make it actually work was more of a pain. It's not pretty, but here's a receive implementation (with the help of this crc library) <?php class XModem { const SOH = "\x01"; const EOT = "\x04"; const ACK = "\x06"; const NAK = "\x15"; const CAN = "\x18"; const C = "C"; private $channel; private $channelBuffer; private $outFile; private $lastPacketData; /** * @param resource $channel * @param resource $file * * @return void */ public function receive($channel, $file){ $this->channel = $channel; $this->outFile = $file; stream_set_blocking($channel, false); $lastPacketNumber = 0; do { $packet = $this->readPacket(); if (!$packet){ if ($lastPacketNumber === 0){ $this->writePacket(self::C); } else { $this->writePacket(self::ACK); } continue; } if ($packet[0] === self::SOH){ $packetNumber = $this->packetNumber(substr($packet, 1, 2)); $data = substr($packet, 3, 128); $receivedCRC = substr($packet, -2); $calculatedCRC = $this->calcCRC($data); if (($packetNumber === $lastPacketNumber + 1 || $packetNumber === 0 && $lastPacketNumber === 255) && $calculatedCRC === $receivedCRC){ $lastPacketNumber = $packetNumber; $this->updateReceiveFile($data); $this->writePacket(self::ACK); } else { $this->channelBuffer = ''; $this->writePacket(self::NAK); } } else if ($packet[0] === self::CAN){ $lastPacketNumber = 0; fseek($file, 0); ftruncate($file, 0); $this->writePacket(self::C); } else if ($packet[0] === self::EOT){ $this->finishReceiveFile(); $this->writePacket(self::ACK); } } while (!feof($channel) && !$packet || $packet[0] !== self::EOT); } private function updateReceiveFile($data){ if ($this->lastPacketData){ fwrite($this->outFile, $this->lastPacketData); } $this->lastPacketData = $data; } private function finishReceiveFile(){ fwrite($this->outFile, rtrim($this->lastPacketData, "\x1a")); } private function readPacket(){ $packetType = $this->readChannelBuffer(1); if ($packetType === self::SOH){ $pn = $this->readChannelBuffer(2); $data = $this->readChannelBuffer(128); $crc = $this->readChannelBuffer(2); $packet = $packetType . $pn . $data . $crc; } else { $packet = $packetType; } return $packet; } private function readChannelBuffer($length){ $startTime = time(); while (strlen($this->channelBuffer) < $length && time() - $startTime < 10){ if (!$this->bufferInput()){ usleep(100); } } $data = substr($this->channelBuffer, 0, $length); $this->channelBuffer = substr($this->channelBuffer, $length); return $data; } private function bufferInput(){ $byteCounter = 0; do { $r = [$this->channel]; $w = $e = []; $readable = stream_select($r, $w, $e, 0, 0); if ($readable){ $dataRead = stream_get_contents($this->channel); $byteCounter += strlen($dataRead); if ($dataRead){ $this->channelBuffer .= $dataRead; } } } while ($readable); return $byteCounter > 0; } private function writePacket($data){ $total = strlen($data); $written = 0; do { $dataToWrite = substr($data, $written); $written += fwrite($this->channel, $dataToWrite); fflush($this->channel); } while ($written < $total); } private function packetNumber($pnBytes){ $n1 = ord($pnBytes[0]); $n2 = ord($pnBytes[1]); if ($n1 + $n2 !== 255){ return null; } return $n1; } private function calcCRC($data){ $o = new mermshaus\CRC\CRC16XModem(); $o->update($data); return $o->finish(); } } Requires some terminal setup to work properly. I eventually included this code in my test script to fix terminal problems, but it creates it's own problems (can't ctrl+c the script). system('/usr/bin/stty -cooked -echo'); register_shutdown_function(function(){ system('/usr/bin/stty cooked echo'); }); I'll leave implementing send and other improvements for the reader.
  7. Protocol seems simple enough, you could probably create an implementation of it without a lot of work.
  8. Yea, It's briefly noted in the documentation for the Iterator class. I first noticed this behavior when working with FilterIterator. Seems kind of strange and dumb to me, but oh well.
  9. You could just read the results into an array, then use that for your two loops. $query = "SELECT colname FROM table"; $result1 = $db->SelectLimit($query,10,-1); $resultData=[]; while (!$result1->EOF) { $resultData[]=$result1->Fields('colname'); $result1->MoveNext(); } // 1ST RUN foreach ($resultData as $colname){ echo $colname.'<br>'; } // 2ND RUN foreach ($resultData as $colname){ echo $colname.'<br>'; }
  10. Yes, you can use variables in your path, so you could define a separate prefix for each environment. However, usually it's easier to use the built in __DIR__ constant and build a path that's relative to the current file. For example: include(__DIR__.'/my_file.php');
  11. If you install it on the target system with composer, then composer will install whichever version of the package is compatible automatically, just make sure you have your version constraint for the package setup correctly. If you're trying to pre-package a release and want to make a 5.6 version and 7.1 version, you could have both version of PHP installed and run composer with the appropriate version.
  12. You have output before the session_start call. Probably blank lines before your <?php tag. Remember, anything outside of php tags is output sent to the browser, even blank lines/spaces.
  13. if($subject='') { $error_message .= 'You must select a Category.<br />'; } This is incorrect code, as you're assigning an empty string to $subject rather than comparing to one. The if won't trigger because an empty string is a false-like value, but your subject will be blank in the email. You need to use double-equals (==) for comparison. if(($subject)!=('Questions'||'Report Problem'||'Suggestion'||'Other'||'Website Problem')) { $error_message .= 'The Category you entered is invalid.<br />'; } This is incorrect code, as you cannot compare against multiple values in that way. If you wanted to test against multiple values, you need to repeat the variable name and condition for each one, as in: if ($subject != 'Questions' || $subject != 'Report Problem' || ...){ That would be correct code, but incorrect logic as it would end up being always true. If $subject == 'Questions', then it's != 'Report problem' and the condition is true. Likewise, if $subject == 'Report Problem', it is != 'Questions' and the condition is true. The correct logic would be to use and (&&) as in if ($subject != 'Questions' && $subject != 'Report Problem' && ...){ Alternatively, in this type of situation, you can use the in_array function and check against an array of values. This is shorter and more similar to your original code. if (!in_array($subject, ['Questions', 'Report Problem', ...])){ Finally, $string_exp = "/^[A-Za-z .'-]+$/"; if(!preg_match($string_exp,$name)) { $error_message .= 'The Name you entered does not appear to be valid.<br />'; } While this is not incorrect like the others, it's generally recommended to not try and validate a persons name (beyond something like maximum length / not blank). There's really no specific format for a persons name to validate against, and doing so means you'll always end up eventually telling someone that their name is not valid.
  14. source: Mysql Manual - JOIN Clause Your query would be interpreted as if it were: select * from trk_races a inner join drivers d left outer join ( select race_winner, count(race_date) as wins from trk_races where race_winner > '' and Season='$selyr' group by race_winner ) w on w.race_winner = a.race_winner on 1=1 Essentially your left join becomes like a sub-join of the drivers table. When you do a join like that you can only reference the parent join table (d) or some same-level sibling table (none here) in your on clauses. Table a does not meet either of those conditions (it's a sibling of the parent) so it's invalid in your left join's ON clause. In case it's unclear, when I say sibling tables I mean something like this. select * from a left join b inner join c on c.Id=b.cID inner join d on d.Id=c.dID on a.Id=b.aID Table c is a sibling to table d, so it can be used in the on condition, as can table b as it's the parent table. Table a cannot because it's the parent's sibling.
  15. Are you sure you're getting results from your query? Your query/code doesn't make a whole lot of sense anyway. Your querying for records where SubRenew = 30, and the only data you're using as a result of that query is the SubRenew column which is guaranteed to be 30 at that point so why bother?
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.