Jump to content

kicken

Gurus
  • Posts

    4,704
  • Joined

  • Last visited

  • Days Won

    179

Everything posted by kicken

  1. http(s) means http or https, and you are certainly using one or the other if your PHP code is being processed. If your page is loaded via http://... or https://... you cannot use a file:// reference in it, the browser simply will not allow it. Your image must be accessed via http as well, so you need to generate the appropriate URL to put into your image tag.
  2. A local file reference needs to use a file:// url, not just the local path. However, a webpage served via http(s) cannot attempt to load a local file as a resource, the browser won't allow it as a security measure. What are you trying to do that you want to be able to use local file paths?
  3. On an unrelated note, if you're trying to redirect a user away because they do not have permission to access the page, you need to exit; after your call to header() otherwise the script will keep going and still do whatever it is they are not supposed to be doing. On a more related note, you code could probably be cleaned up a lot if you switched to using RecursiveDirectoryIterator / RecursiveFilterIterator. For example: <?php class PrefixFilter extends RecursiveFilterIterator { private $prefixList; public function __construct(RecursiveIterator $iterator, array $prefixList){ parent::__construct($iterator); $this->prefixList = $prefixList; } public function accept() : bool{ /** @var SplFileInfo $current */ $current = $this->current(); $path = $current->getPathname(); $path = strtr($path, '\\', '/'); $pathLength = strlen($path); foreach ($this->prefixList as $prefix){ $length = min(strlen($prefix), $pathLength); if (strncmp($path, $prefix, $length) === 0){ return true; } } return false; } public function getChildren() : RecursiveFilterIterator{ return new self($this->getInnerIterator()->getChildren(), $this->prefixList); } } header('Content-type: text/plain'); $root = './datausers'; $prefixList = [ $root . '/TEAM', $root . '/PERSONAL/' . strtoupper($_GET['user']) ]; echo 'Found the following files for the selected user:', PHP_EOL; $iter = new RecursiveDirectoryIterator($root); $iter = new PrefixFilter($iter, $prefixList); $iter = new RecursiveIteratorIterator($iter); foreach ($iter as $item){ if ($item->isDir() && $item->getFilename() === '.'){ echo 'Directory: ', $item->getPath(), PHP_EOL; } else if ($item->isFile()){ echo 'File: ', $item->getPathname(), PHP_EOL; } } The directory iterator takes care of scanning the directories and you can choose what you want/don't want with the filter class. Here it's based on a simple prefix filter but you could make it more complex if needed. Once all that's setup getting the list of files and folders is a simple foreach loop over the iterator.
  4. empty() will see the string '0' as an empty value, so a numeric input where the user might need to enter '0' will have issues with using empty. I tend to just use isset() if necessary, the != NULL second check you have is not necessary, isset() treats a NULL value as not set. What I do is just side-step the whole "does it exist?" issue by ensuring my inputs always exist with the help of array_fill_keys. A simple bit of code that looks like this: $data = array_fill_keys(['all', 'my', 'inputs'], null); $data = array_replace($data, array_intersect_key($_POST, $data)); //$data = array_map('emptyStringToNull', $data); // function I have to convert an empty string to null. Optional. var_dump($data); After that $data will always contain the three keys all, my, and inputs and they will either be the value entered in the form or null. As you discovered that doesn't work. You can't combine your validation and definition like that. Keep your validation separate. I find using an array over .= is easier/better. You can implode your array in the end if you want a string value. $name = $_POST['name'] ?? null; $address = $_POST['address'] ?? null; $errors = []; if (!$name){ $errors[] = 'Name is required.'; } if (!$address){ $errors[] = 'Address is required.'; } echo implode("\r\n", $errors);
  5. both_tables is just the name of the virtual-table created by the two inner select queries. A name is necessary there, but it doesn't have to be both_tables, that's just a descriptive name. You can use a different name if you wanted.
  6. It's unclear to me how your code is structured, but you need to be sure you're loading each of the files and defining the constants before trying to use them. So if you had page.php that was trying to use your function, you'd structure it such as: <?php require '../config/config.php'; require 'functions.php'; if ($_SERVER['REQUEST_METHOD'] === 'POST'){ process_database($_POST); } //... Include the config file first so the constants get defined. Include the functions file to define your functions, then call your function where needed.
  7. Your missing the configuration that integrates PHP with your web server. This may be provided by a different package that you need to install or you might have to update the configuration by hand. Search how to install php on whatever webserver you're using on debian and you can probably find instructions.
  8. I've only ever used VMs in a cloud service and those pretty much have a fixed cost. Running an infinite loop isn't going rack up some gigantic bill. Those citations to me read mostly as people just jumping into something they don't understand and getting burned by it. Taking the time to learn how something works and use caution helps to avoid such costly mistakes. For example what that guy in the first story learned about not using the high defaults when testing is something I would have done out of the gate. Whenever I'm testing something that has the potential to run-away like that I always implement a hard stop (ie, die after $x loops) and start with a small concurrency factor (2-4 concurrent threads) until I'm sure things are behaving properly. Such precautions probably would have limited their bill to less than $1000 it sounds like. Still rough, but not destroys the company rough. Secondly, test locally as much as possible. It doesn't matter if you end up in big loop when your just testing on local hardware as you're not getting charged for usage. Their issue of "If there’s a back link to the previous page, the Cloud Run service will be stuck in infinite recursion" never would have made it to the cloud service for me as I would have caught that during local testing.
  9. How to use mail forwards.
  10. My suggestion doesn't violate this. The user is saved to the UserListener class not the HelpDeskClient.
  11. Pretty much. The doctrine event system is specific to it and the related database operations. The Symfony system is generic and can be used as needed. It's a lifecycle event, but not a callback. Doctrine makes a distinction between the two things. A lifecycle callback is a method defined directly on the entity that gets called. Eg: class AbstractUser { public function postUpdate(){ //... } } A lifecycle event that is not a callback requires a listener class like you have, but it needs to be a lifecycle listener not an entity listener. Those are tagged as doctrine.event_listener. I'm not sure if you can just change the tag to make it work or if it will need to be split into two separate classes. Assuming just changing the tag gets your flush event working, you could just store the user as a property on the class. private $user; public function prePersist(AbstractUser $user, LifecycleEventArgs $event){ $this->user=$user; $this->helpDeskClient->addUser($user); $this->dispatcher->addListener(KernelEvents::EXCEPTION, [$this, 'exceptionHandler']); } Something to consider is how this would work if you update multiple AbstractUser's at the same time.
  12. Doctrine uses a different events system than Symfony, that's why your code doesn't get executed. You would need to inject Symfony's event dispatcher and tie into it that way. You would also need some way to remove your event listener when the query is completed successfully, otherwise you might have it trigger for some other unrelated exception that gets throw later on in your script. Something like this would be the code then: final class UserListener { private $helpDeskClient; private $dispatcher; public function __construct(HelpDeskClient $helpDeskClient, EventDispatcherInterface $dispatcher){ $this->helpDeskClient = $helpDeskClient; $this->dispatcher = $dispatcher; } public function prePersist(AbstractUser $user, LifecycleEventArgs $event){ $this->helpDeskClient->addUser($user); $this->dispatcher->addListener(KernelEvents::EXCEPTION, [$this, 'exceptionHandler']); } public function postFlush(){ $this->dispatcher->removeListener(KernelEvents::EXCEPTION, [$this, 'exceptionHandler']); } public function exceptionHandler(ExceptionEvent $event){ $this->helpDeskClient->rollback(); //or whatever. $this->dispatcher->removeListener(KernelEvents::EXCEPTION, [$this, 'exceptionHandler']); } } That might work out ok. If for some reason it doesn't, my alternative solution would probably be to create a custom event that gets fired when the user update fails and listen for that. Something like: final class HelpdeskRollbackListener implements \Symfony\Component\EventDispatcher\EventSubscriberInterface { private $helpDeskClient; public function __construct(HelpDeskClient $helpDeskClient){ $this->helpDeskClient = $helpDeskClient; } public static function getSubscribedEvents(){ return [ UserUpdateFailed::class => 'rollback' ]; } public function rollback(UserEvent $event){ $this->helpDeskClient->rollback($event->getUser()); } } final class UserUpdateFailed extends Symfony\Contracts\EventDispatcher\Event { private $user; public function __construct(AbstractUser $user){ $this->user = $user; } public function getUser(){ return $this->user; } } final class YourControllerOrWhatever extends Symfony\Bundle\FrameworkBundle\Controller\AbstractController { private $em; private $dispatcher; public function __construct(EntityManagerInterface $em, Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher){ $this->em = $em; $this->dispatcher = $dispatcher; } public function indexAction(){ $user = new AbstractUser(/*...*/); try { $this->em->transactional(function() use ($user){ $this->em->persist($user); }); } catch (PDOException $ex){ $this->dispatcher->dispatch(new UserUpdateFailed($user)); throw $ex; } } }
  13. substr returns a string that consists of $length characters starting at $offset. If you don't specify what length, then it defaults to the end of the input string. If you want a single character at a specific index then you must specify a $length of 1, or use array syntax on the string to access the desired offset. $str = 'Hello'; $firstLetter = substr($str, 0, 1); //or $firstLetter = $str[0];
  14. If you simply var_dump($orders); then it will show you what exactly is contained in that variable. I'm guessing is just a multi-dimensional array and not JSON like your original post implied. If so, you'd just access whatever keys you need or foreach over them all. foreach ($orders as $order){ foreach ($order as $key => $value){ $orderDetails .= $key.': '.$value.'\n'; } //... }
  15. Use a foreach loop above the $body and create a new variable containing the order details as a string, then use that variable in $body. $orderDetails = ''; foreach ($orders as $order){ $orderDetails .= $order . '\n'; } It seems your orders are JSON encoded, so you'll probably want to json_decode them and format them nicely within that foreach loop.
  16. In the menu bar, Database -> Reverse Engineer... will try and generate a diagram from your existing database. Is that what you're looking for?
  17. IDE's don't run code, they just analyze it. In the code above, your IDE can't figure out what the name of the constant being created by the define call is because the name is a dynamic value returned by the strtoupper function. You might be able to configure VScodium to not treat this as an error. I use PHPStorm and it highlights this as just a Warning not an Error. To make the problem go away though you need to define your constants individually in a way the IDE can understand.
  18. It is if you're doing multiple posts like you are describing, but that's not how this is typically supposed to work. The typical sequence only involves one POST. You load a form using GET After filling out the form you submit it using POST The server saves the data from the POST and issues a redirect to another page. The basic idea is that your POST request returns a redirect, not a page to be displayed. If your POST request returns a page to display then trying to refresh that page requires re-sending the POST request, data and all.
  19. I ran both your C# code and PHP code from your original post with the same inputs: $key = '01234567'; $iv = "\x01\x12\x23\x34\x45\x56\x67\x78"; $value = 'param=value'; And I get the same output from each code: C# Output: sFi4JhEGhA4awvJPqeK0Gg== PHP Output: sFi4JhEGhA4awvJPqeK0Gg== So it would seem likely your issue is that you're just not using the same inputs for both codes and that's why you get different outputs. You seem unwilling to give any details on what inputs you're using though so it's not really possible to provide you any further help until you do. Generate a new key that you can post without worry and then show us how you're running your code and the output you're getting.
  20. Are you specifically interested in just the debugging process with XDebug, or about general development? I've debugged remote code before and it's worked out just fine without any real issues that I can remember. You need to install XDebug on the web server and be able to open the debugging port on the web server so that PHPStorm can connect. If you can't do either of those (ie, shared hosting environment) then you'll have issues. Developing remotely is more annoying due to needing to sync the files in some way when you make changes. That's not really a PHPStorm specific problem though. PHPStorm can certainly handle it, I just find the workflow annoying so I don't do it.
  21. I don't use annotations, so N/A. PHPStorm will apply some basic formatting to doc blocks, but trying your sample annotation it doesn't seem to do anything with it outside of wrapping long lines. As far as style, do whatever you like, just be consistent.
  22. You can't execute a powershell script on the end-user's machine if that's what you're trying to ask. If you want the end-user to be able to trigger the script on your server then you just make a request the PHP script which will then execute the powershell script. You can make that request with a simple link or form button or you could do it via javacript in the background.
  23. postMessage serializes the data that you want to send. That means that for the most part, only simple data is able to be sent, not complex stuff like functions or objects with methods. What you need to do is define MyClass on both pages and give it a way to be serialized to a string or simple object on the sending page and then unserialized back into the full object of the receiving page.
  24. That would be the browser choosing this option: It's taking that raw binary data and interpreting it as a text string and displaying the results. Of course, the result is a bunch of nonsense because that raw binary data isn't supposed to be interpreted that way.
  25. In the original example: foreach ($queryResults as &$row){ represents the loop for your query results processing. That'd be your while loop. So you'd replace the foreach with your while loop, not put the foreach inside your loop. Using the while loop means you have to unset($row) at the end to break the reference before the next iteration also, otherwise the first row data would just keep getting overwritten by future rows. The foreach handles this by using & before the variable, the while loop doesn't. $tree=[]; $map=[]; while ($row = mysqli_fetch_array($query)) { //whatever else you need to do ... if ($row['ParentId']){ $map[$row['ParentId']]['children'][] = &$row; } else { $row['children']=[]; $tree[] = &$row; } $map[$row['id']] = &row; unset($row); // break the reference for next iteration. } Your error is a result of your query returning zero rows and the way you had your code structured. Since you just copy/pasted my code into your loop rather than integrating it, $tree is never declared when no rows are returned by the query making it essentially NULL. Since the function wants an array and not NULL that causes an error to be thrown.
×
×
  • 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.