Jump to content

requinix

Administrators
  • Posts

    15,065
  • Joined

  • Last visited

  • Days Won

    414

Community Answers

  1. requinix's post in javascript select option by data-value was marked as the answer   
    Somewhere in your code you wrote "new Choices(...)". Hopefully you assigned that to a variable, like the example does with "const example =".
    Call setChoiceByValue("AFG") on that variable.
  2. requinix's post in Can not access to the website and no content displayed was marked as the answer   
    The error message seems to rather clearly indicate that there is no "app" database. Have you tried looking into that?
  3. requinix's post in for loops, learning was marked as the answer   
    A loop isn't a mystical thing that does work for you. It's merely a tool. A means to an end.
    So the question you should be asking is whether something, a page or a function or whatever, needs loops to perform its necessary tasks. And odds are that if you have more that one of some things then you'll need a loop to process them.
     
    So you have a one-to-many relationship? That is, every single row in "table" has one or more corresponding rows in "anothertable"?
    You're absolutely right to consider an INNER JOIN. It will be far, far more efficient for you and your database if you issued one single query to retrieve all the data at once instead of one for the first table and another N for the second table.
    But you're also right that it won't be obvious where one id/name stops and one id/name begins...
    ...unless you do what is probably going to sound obvious in retrospect: make the query also return the id and name.
    SELECT t.id, t.name, at.field1, at.field2 FROM table t JOIN anothertable at ON t.id = at.field3 ORDER BY t.name, at.something When you go through those results (with a loop), track the previous id and keep an eye out for when it changes. Note that sorting the results is key for this to work, since otherwise there's no particular guarantee on whether all the rows for a given table.id show up together, but it's also probably something you'd want to do anyways.
    Essentially,
    previous id = null foreach row { if current id != previous id { new heading } print row previous id = current id }  
    In practice it tends to be a little more complicated than that, depending on what kind of output you want - especially if it's HTML, and especially especially if you want syntactically valid HTML.
  4. requinix's post in Problem with mysql retrieval was marked as the answer   
    Is "gone" nullable?
     
    Meaning what, exactly?
  5. requinix's post in Macro substitution was marked as the answer   
    If your code has and $$s in it then it is doing something terribly wrong.
    Use an array for the postal codes like a normal person.
  6. requinix's post in PHP https with $_SESSION send to another page was marked as the answer   
    Browse around your site and make sure the browser always says the page is encrypted, or at least it never says it isn't encrypted.
    With Chrome, for example, a padlock icon on the left of the address bar means it's HTTPS.
  7. requinix's post in Has something changed that I am not aware of? was marked as the answer   
    I can't tell what your other account is. What's the username or email? You can post it or PM me.
    I'm being stupid. It should be obvious what the original account is.
    I do see the account being locked from too many unsuccessful login attempts from 37.147.174.213, but that lock has since expired (while the site was offline). You should be good to go now.
    I can't really speak to the support ticket thing... Nibble Netwrx owns PHP Freaks so that's why you got that email from them.
  8. requinix's post in Cron Job API Integration was marked as the answer   
    You'll probably have to make some other minor changes so that this script can run from a cronjob, but
    Essentially the change you need to make is to take all of that code, which works for a single page of data, and stick it inside of a loop that goes through all of the pages. Starts at page 1 (or perhaps 0), runs the code that you have now but edited to use that page number, then the loop moves to the next page and starts again until eventually there are no more pages.
  9. requinix's post in Downloading selected multiple file was marked as the answer   
    Look at the examples and maybe try some Google searches for using PHP to download multiple files with a ZIP archive. There's a lot of information out there and it isn't too hard to find samples you can reference.
  10. requinix's post in Redirect domains to a URL+domains was marked as the answer   
    What? Sure you do: that second server you were planning to use. The one where the domains redirect to, and where you were going to redirect from.
    Take that, add a virtualhost for a catch-all domain (so any domain that doesn't match some other known site), then give it a redirect to go to destinationtarget.com/(requested domain). It's one configuration that handles the redirects for every single domain you throw at it - assuming you all want them to use the same pattern for the redirect.
    Then you change the DNS for the domains you want to redirect from such that they resolve to that second server. Browser will look up "domain1.com" or "domain2.com" or "domain3.com", all of them resolve to that second server, browser asks the server for the webpage at that domain, server responds with a redirect to destinationtarget.com.
    In fact, that "second server" can simply be whatever server hosts destinationtarget.com. I mean, this redirect business is very lightweight. It's not going to add any noticeable load to anything.
    So there. You have a server that hosts destinationtarget.com. Give it a new configuration for a catch-all domain that does the redirect I said, then update the domains to point to that server. And if you decide to handle some redirected domains differently then you don't have to update DNS for anything.
  11. requinix's post in Executing time consuming functions in an EventLoop was marked as the answer   
    In this case it's about using the generator as a coroutine. Generators can suspend execution and return to some caller, then that caller can have the generator resume.
    The use case here is that your doWork becomes a generator, and it yields (suspends) every email or so. When it suspends ReactPHP would have a chance to execute as it needs (ie, run through the event loop), and when it's ready it has doWork continue. Rinse and repeat until hair is sufficiently washed.
    https://3v4l.org/qlXCj
     
    As long as doWork is running, ReactPHP's loop will not execute. Because it's not truly asynchronous - it just looks that way.
    The basic problem you have is that doWork takes too long. The basic solution is to split the work according to whatever is not "too long". Since your metric is time, I suggested running work until some suitable amount of time has passed. Like one second.
    doWork is probably self-contained, right? It determines what work needs to be done and does it. You'd refactor that so that determining the work to be done happens before doWork, then doWork goes through that set until either too much time passes or it runs out of stuff.
    class DoesWork { private $work = []; public function __construct() { $this->work = ???; } public function addWork($item) { $this->work[] = $item; } public function doWork() { // exact code varies, but basically... $now = microtime(true); $end = $now + 1; while ($this->work && $now < $end) { $item = array_shift($this->work); // whatever $now = microtime(true); } } public function hasWork() { return !empty($this->work); } } // setup $worker = new DoesWork(); // inside the event loop, if ($worker->hasWork()) { $worker->doWork(); } If you look closely, you'll notice the code structure looks similar to what was in that 3v4l link...
  12. requinix's post in html table with data from 2 sources was marked as the answer   
    That is the correct answer. Why do you not want to do it?
  13. requinix's post in For Each Loop on Common Value in DB was marked as the answer   
    First you'll have to sort the results by the type. Because otherwise stuff will bounce between one type and another. Then you should probably sort by a secondary another field - I suggest the item name, since that's what the user sees.
    Really, most of the time you're running a query for data that gets displayed to a user, you'll want to sort by something. Even if you don't need anything grouped or sorted alphabetically, picking and sorting by a unique column (like an ID) guarantees that you'll get the same data in the same order every time.
    Anyway, when you have that sorting, your loop will need to know when the type changes. That means remembering what the previous one was.
    Get yourself a variable for it. Start it off empty. Inside the loop, if the current type doesn't match the previous type (and the first row definitely will not) then that means you need to start a new group. If there was a previous type then there was a previous <optgroup> already going for it and you'll need to close that out, then either way you start the new <optgroup>.
    Finally, you need to think about that last group. When the loop finishes you'll have been working on one group but the <optgroup> will still be open. So close that one out too.
  14. requinix's post in Error inserting image into mailchimp was marked as the answer   
    According to the documentation, file_data is not simply the raw contents of the file. Take a look. Do you know what you need to do to fix that? It could be MailChimp is trying to un-
  15. requinix's post in Mapping data to Models was marked as the answer   
    Mapping tends to be a thing when you're working with a framework that already has its own model system - and mapping practices.
     
    If I were implementing this idea on my own then I would keep it simple: form model's properties match the form fields and it has load/save methods to import/export a database model, or models as the case may be (and obviously another method, likely inherited, for populating from request data).
  16. requinix's post in gmail imap help was marked as the answer   
    It needs to be on. If it keeps turning off, I don't know, but it does have to be on for this to work.
  17. requinix's post in loop through files in directory was marked as the answer   
    The issue is that file_get_contents doesn't work on directories - "Permission denied" is Windows' weird way of telling you that.
     
    If you want all files in a directory, and including the paths with the names, then use a simple * wildcard with glob().

    glob($dir . "\\*")And note the escaped backslash since it's a double-quoted string. (Or use forward slashes.) The fact that
    "C:\php\Inventories\Json"worked without them is a coincidence: there are no \p \I \J metacharacters.
  18. requinix's post in Catching multiple exceptions was marked as the answer   
    Only if you have PHP 7.1.
     
    Since backtrace information is decided at instantiation and not when thrown (unlike other languages), you could do the less glamorous
     

    } catch (Exception $e) { if ($e instanceof PDOException || $e instanceof BarException) { $this->pdo->rollBack(); $rsp = $e->getMessage(); } else { throw $e; } }but for only two lines of code it's not worth the added complexity. 
    That said, you should rollback the transaction for every exception, so I suggest changing your code regardless. Using a finally means you can skip the $rsp variable too.

    $e = null; try { $this->pdo->beginTransaction(); $this->doQuery(); return $this->doMethodWhichThrowsBarException(); } catch (PDOException $e) { return $e->getMessage(); } catch (BarException $e) { return $e->getMessage(); } finally { if ($e || !$this->pdo->commit()) { $this->pdo->rollBack(); } } Demonstration
  19. requinix's post in Question about authentication was marked as the answer   
    Unless you have a weird PHP configuration that's possible but one I've never actually seen anyone do (because it's so stupid) then data in $_SESSION is safe. But remember that sessions use cookies, so if a bad person gets a hold of a good person's session cookie then they could hijack their session. There's a lot written on the subject of session hijacking, but that's besides the point.
    Also consider that people using shared hosting are sharing the same machine with other hosting accounts, and since sessions are normally stored as files, it's possible (again, depends on the server configuration) for one of those other accounts to look at session data.
     
    Since it's safe, storing only the ID is fine. Storing the password is flat-out bad, regardless of hashing or encryption, and that applies to dedicated hosting as well.
     
    Speaking of, passwords should be hashed. Not encrypted. Hashing can't be reversed but encryption can be. Use PHP's password_hash/_verify functions for that.
     
    When a user wants to change their password, you should prompt them to enter their current one anyways - either through a secondary login screen (eg, "confirm your account") or through a confirmation box in the form. You should then change their session ID via session_regenerate_id(), which is actually something you should do on a regular basis anyways but is a bit more complicated than just that.
     
    As for catching the password change, that's a question for you. Do you want to boot a secondary session because the password changed on another one? I probably wouldn't. You can always give the user a sort of "log out all other devices"-type action; if that was in place then you would have to check the DB on every page load anyways.
  20. requinix's post in OOP/OOD advice was marked as the answer   
    There's a fair bit of boilerplate code in your factory - particularly in createUserModel. You'll find yourself repeating that in all the factories.
    Consider any of
    a) Subclassing the factory, so the parent class handles the general work and the child classes provide the specialized logic for the particular models
    b) Doing something similiar with the model; a parent class would handle the constructor and setting properties while the children implement any other logic they need
    c) Using traits to at least move the logic into a centralized place, if you don't want a class hierarchy
     
    For DI, you've already changed it up a bit so what I said is less applicable now.
    Having to pass around various classes and such in constructors is annoying, right? It provides a sort of "perfect" dependency injection because you can customize absolutely everything, but at the cost of increasing complexity and of being a nuisance to the developer. You can take a step back from that and use a sort of (gasp!) registry instead; as a demonstration, I use something like

    $this->tableGateway = Dependencies::get(userTableGateway::class); final class Dependencies { private static $classes = []; private function __construct() { } public static function get($class) { if (isset(self::$classes[$class])) { $class = self::$classes[$class]; } return new $class(); } public static function register($dependency, $class) { self::$classes[$dependency] = $class; } }But that's one of many ways, and they all have advantages and disadvantages. Use whatever works for you.
  21. requinix's post in How do I put the ' in my link? was marked as the answer   
    Use a backslash to escape, not an apostrophe.
  22. requinix's post in foreach loop - multidimensional array was marked as the answer   
    Seems you're a little confused here. $row is the keys in the user_cards object ("1", "2", etc.), $v is the corresponding object; $key is "num_owned/num_used/is_locked", and $val is the corresponding value.
     
    So looking at $val doesn't make sense.
     
    Get rid of the inner foreach loop. It gets you $key and $val and those are worthless. Instead, decide what to do with $v if $v['num_owned'] > 0.
  23. requinix's post in Javascript Submit Form was marked as the answer   
    How about we try to solve the earlier problem instead?
     
    What conflict? What was it doing and what was it supposed to be doing? Any error messages? And most importantly, what was the code?
  24. requinix's post in Simple task for you REGEXers out there was marked as the answer   
    Note that what you have will check if there's that 5-4 somewhere inside $input. As in it will quite happily match with

    $input = "a bunch of stuff then 12345-6789 and then more stuff";If you want to make sure $input has only that 5-4 then you need ^ and $ anchors to mark the beginning and end of the string.
    '/^\d{5}-\d{4}$/'
  25. requinix's post in Where is the mistake? was marked as the answer   
    Your form has method="get" but you are using $_POST.
     
    method=get goes with $_GET, method=post goes with $_POST.
×
×
  • 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.