Jump to content

kicken

Gurus
  • Posts

    4,704
  • Joined

  • Last visited

  • Days Won

    179

Everything posted by kicken

  1. Using a reference means you have two variables that point to the same underlying value. As such changes to that value by either variable are reflected by both variables. In the case of passing $arr by reference as the function parameter this means any changes you make to $arr within the function will be reflected in the variable originally passed to the function. That is the theory behind using a referenced for $k also, but PHP does not allow the key in a foreach to be by-reference so it doesn't actually work.
  2. You could get fancy and try to use something like array_walk/array_map etc, but ultimately that's the same as just looping over the array with foreach and renaming the key. I'd just do the foreach loop and call it a day, I don't think you can really do much better than that. Make a function out of it so you can re-use the logic elsewhere if need be. Off the top of my head, something like this should work: function rename_keys($input, $from, $to){ $out = []; foreach ($input as $arr){ if (isset($arr[$from])){ $arr[$to] = $arr[$from]; unset($arr[$from]); } $out[] = $arr; } return $out; } Fancier array_map way: function rename_keys($from, $to){ return function($arr) use ($from, $to){ if (isset($arr[$from])){ $arr[$to] = $arr[$from]; unset($arr[$from]); } return $arr; }; } $new = array_map(rename_keys('name', 'label'), $original);
  3. If you want a more user-friendly ID, make that a secondary Unique column. Use a standard INT AUTO_INCREMENT column internally to link tables and what not, then in another column insert your generated ID. If you get an error due to the UNIQUE constraint, generate a new ID and try again.
  4. If you're using the browsers native picker with a type="date" field then you pretty much just have to accept how that UI looks and works, there's not much you can do to change it. If you really need to be able to select the entire field, then use a type="text" field with your own picker implementation (such jQuery UI's datepicker). Or just use a select box with a list of dates if that is the look you're going for.
  5. If you want to store a large amount of text in a column, then you'd do as the error suggests and use the TEXT data type. This type stores the text in a separate location from the row and then just stores a pointer to it within the row itself. That said, you could also re-evaluate how big you need the columns to be. For example if your 500 word block of text had an average word length of 6 characters, you'd be using only about 3,500 characters total meaning you could make your columns 4,000 characters long rather than 8,000. You could also re-design your DB so you have more rows but less columns. For example: create table result ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY , userhash VARCHAR(50) NOT NULL , resultNumber INT , ready VARCHAR(3) NOT NULL , result VARCHAR(8000) NOT NULL ) Instead of 3 ready/result columns, you have 3 rows, each with a single ready/result column plus a column indicating the result number (1, 2, 3...). This is known as normalization and is generally a good idea. If you find yourself having a bunch of numbered columns in a table, that is a good sign you should re-think that design. Think about your design now. What happens if next month you need to add a 4th result? You'd have to add more columns, which could cause all kinds of problems. All the existing rows would have to be expanded to include the new columns. Your queries may break if you are doing something like SELECT * due to the new columns. You might fail to add the columns do to the row size limit you already discovered. With the alternate row based design you just add another row with resultNumber=4, no problems at all. There's no limit to the number of results you could potentially have with the alternate design. If you want to have a limit, you enforce it in your code. If you need to raise the limit later, it's a simple code change, not a whole database refactor.
  6. For one system where I needed tokens for various reasons, I stored the tokens into a separate table along with a small bit of data. I had a separate tokens table with columns: TokenId, TokenHash, CreatedOn, ExpiresOn, RedirectTo, ContextData, InvalidatedOn The basic premise of how it all worked was that wherever a token was needed, I'd call a class which would generate the token and store it, giving the calling code back the ID and plain text value. All the token validation was handled by one controller with a URL such as http://example.com/validate-token/$token. That controller would verify the token exists and hasn't expired / been invalidated and if so add the token to a list of validated tokens in the current session. If the token validates successfully it then redirected to the controller associated with the token. The final controller then looks up the token from the session and can use the associated context data to perform whatever it needs to do. The code ended up looking something like (symfony based): Reset request controller: $tokenManager = $this->getTokenManager(); $context = new ForgotPassword($user); $tokenOptions = new TokenOptions(new \DateInterval('PT3H'), $context); $token = $tokenManager->createToken('forgot_password_reset', $tokenOptions); $code = $token->getTokenPlaintext(); $verifyUrl = $tokenManager->generateUsageUrl($token); //Email user Validate token controller: $tokenManager = $this->getTokenManager(); $token = $tokenManager->validateToken($tokenPlainText); if (!$token){ return $this->invalidResponse(); } return $this->redirectToRoute($token->getRedirectTo()); Reset controller: $token = $this->locateToken(); //Searches the validated tokens list for one with a ForgotPassword context /** @var ForgotPassword $context */ $context = $token->getContextData(); $user = $em->find('AppBundle:User', $context->userId); //handle reset for user. //once reset is complete: $this->getTokenManager()->invalidateToken($token); I've found it to work fairly well so far. The same system handles forgotten password requests, email validations, invitations, temporary access to documents, etc.
  7. Near as I can tell the jQuery code is either not running at all, or not finding any matching anchor tags to attach the event listener too. Add some console.log calls to the code so you can see if it's running and if the event handler is firing. Then based on that result, try and figure out why.
  8. The only way to keep the API key secret is to have the server proxy the requests as you described. Even if you try and get fancy and encrypt the token on the client so that one can't just view-source to grab it, they can always just intercept the request and extract the key that way. Aside from that, the Same-origin rule would prevent you from using external API's generally, unless the API supports Cross-origin resource sharing which is not typical I think.
  9. It appears to be using the Bootstrap tab component. If you look at the documentation you can see some examples of how to activate individual tabs. Basically you select an <a> who's href attribute points to a fragment and call the .tab('show') method. What you can do is attach an onclick handler to all the links which have a fragment URL. In the handler, prevent the default action and then call the tab method, like in the code you show. If you plan to use fragment links for other purposes you'll want to add a check to ensure the fragment is a tab. How you do that is up to you. For example: jQuery(function($){ $('a[href^="#"]').click(function(e){ e.preventDefault(); $(this).tab('show'); }); });
  10. In order to upload an image you require some server-side support for it. Most editors are just client-side scripts that do not interact with the server out of the box. You may be able to extend some of them to add file uploads, but how you do it would depend on the editor you choose to use. TinyMCE is the editor I typically use. If you're willing to spend a little money they have a pre-written extension for handling file uploads called MoxieManager you could purchase and probably just drop in. If you're going for free you could spend some time searching the web for a pre-written plugin or sample code. It would seem the newer versions of TinyMCE provides some support for file uploading, but you still need a server-side component to handle the actual upload. They do provide a simple example which you could extend.
  11. You could also just disable indexes for the images folder by placing this in the .htaccess: Options -Indexes With that Apache will serve a forbidden response if someone tries to access the directory, while still serving the files or 404 not found as appropriate. Of course with either solution, you'll have to remove any existing index.html files to prevent Apache from detecting and serving them.
  12. That means that your query failed. Add error checking/handling to your code. A few other things to note: - You cannot have any code after your return statement. Return causes the function to end right there, everything after it would be ignored. - You shouldn't be opening and closing a connection for each query. Open the connection once at the start of the script. Let PHP close it automatically at the end of the script.
  13. After you create your form, save a reference to it onto this/self, then use jquery's find method to search for elements within that form. // GET FORM HANDLE var obj_form = $("#"+this.idname+" form")[0]; self.form = obj_form; var v = self.form.find("select[name='"+vt[i][0]+"']").val();
  14. According to "Say no to faux bold" on A List Apart, browers may attempt to simulate bold if a font doesn't have a native bold variant. As Muddy_Funster says though, if you want to use bold then you need to import your font with the bold variant. Doing anything else is improper usage on your part, not Mac being wrong.
  15. So long as the end results have the same number and types of columns you can do a UNION of two separate queries. So you're query would look something like: SELECT video_id as id, title, description FROM videos UNION ALL SELECT image_id as id, title, description FROM images That would give you a single result set with three columns: id, title, and description. You'll also likely want some way to know whether a given row is an image or a video. To do that you can add a static column to each query that indicates the row type. SELECT 'video' as rowType, video_id as id, title, description FROM videos UNION ALL SELECT 'image' as rowType, image_id as id, title, description FROM images
  16. Generally I just use an INT field and store the number of seconds. I'll use a function to convert that to a readable format for display, which could be exact or vague depending on what your requirements are. There is also the TIME data type which could be used, but I find INT to be more flexible.
  17. Your second link is to localhost. We can't look at your localhost. It's better if you describe what the actual problem is rather than just saying to look at a URL. Everyone will have their own interpretation of what is correct vs incorrect on a page unless you are specific about what it is you're seeing as being incorrect.
  18. Back in the day browsers would vary with regard to submit buttons and whether it would be sent or not when the form was submitted by pressing Enter in a text field. Google used to actually detect if the button was sent and if so show a little tip about submitting with the enter key. It seems like these days they are more consistent, but I've not done any exhaustive testing on that. Checking for fields to determine if the form was submitted is ok, checking for buttons could be problematic. I would always make my submit check one of either if ($_POST) or if (isset($_POST['someTextField'])). The first version checks if something exists in the $_POST array, the second checks for a specific text field. Since text fields are always submitted the test is reliable. Also as ginerjm says, if someone isn't submitted the data my script expects, then I don't care. If the data isn't correct then the script can't do it's job. So long as the script doesn't throw a bunch of undefined index/variable errors or similar on such requests it's fine. There are reasons for wanting to check what REQUEST_METHOD is, but it's not necessary for basic form processing.
  19. It's mostly an issue of how style and how you want your script to behave. For example, what do you want to happen if someone crafted a special POST request with no data / random data? Assuming your code for handing both the initial form GET request and the submission POST request are in the same file, only checking for the expected field would likely result in the malformed POST being treated as if it were a GET, returning the form with no errors. On the other hand if you check for the POST request method, you'd trigger your submission logic which should then check for expected data and return the form again with errors showing. For simple scripts I tend to just check for the expected form data since that's ultimately what I'm interested in. If the form only has one submit button I check for some field that is guaranteed to be submitted, like a text field. If there are multiple buttons, I check for individual buttons as it's necessary to know which was clicked. For bigger things I'm usually using a framework which will have it's own way of handling things.
  20. All you have to do is download the files and copy them over. It's not like you need root and the ability to install stuff from a package manager. If you can make enough changes on the box to edit your script, then you can use Net_DNS.
  21. A better way to approach this problem is to avoid the use of the ID's and onchange attribute entirely. You can do this by listening to the change event on the parent rows container, and when it occurs finding the elements you need in the dom of the appropriate row. This is assuming the fields used in the change event are also duplicated in each row. I'm assuming that due to their incrementing IDs also. Take this fiddle as an example: /** * Create a clone of the row template and add it to the #rows container. */ function cloneRow(){ //Clone the entire row var $clone = $('#rowsec').clone(); //Clear the input values. Customize this if needed $clone.find('input').val(0); //Remove the ID so there's only one in the dom. $clone.removeAttr('id'); //Add it to the rows container $('#rows').append($clone); } /** * Handle a change event. Within the function `this` refers to the input that changed * We can use jQuery to find the other inputs based on the changed input * then run the calculations. */ function compute(){ var $row = $(this).closest('.row'); var $floor = $row.find('[name=floor]'); var $length = $row.find('[name=length]'); var $width = $row.find('[name=width]'); var $sqft = $row.find('[name=sqft]'); //Do your calculations $sqft.val($length.val() * $width.val()); } //Clone row when button is clicked $('#clone').click(cloneRow); //Handle change events in each row $('#rows').on('change', 'input', compute); <button id="clone"> Clone Row </button> <div id="rows"> <div class="row" id="rowsec"> <div class="col-md-2 col-sm-3 col-lg-1 nopadding"> <input class="form-control input-sm nopadding" type="text" placeholder="Floor" maxlength="4" name="floor"> </div> <div class="col-md-2 col-sm-3 col-lg-1 nopadding"> <input class="form-control input-sm nopadding" type="text" placeholder="Length" maxlength="4" name="length"> </div> <div class="col-md-2 col-sm-3 col-lg-1 nopadding"> <input class="form-control input-sm nopadding" type="text" placeholder="Width" maxlength="4" name="width"> </div> <div class="col-md-2 col-sm-3 col-lg-1 nopadding"> <input class="form-control input-sm nopadding" type="text" placeholder="Sqft" maxlength="4" name="sqft"> </div> </div> </div>
  22. For Thunderbird you can just copy it's Profiles folder and profiles.ini file. On Windows this is in %APPDATA%\Thunderbird. Not sure about the other applications or other OS since I don't use them.
  23. While using a static variable or a class member to track things isn't bad, I generally find it best to avoid those solutions unless there is a compelling reason to use one. Not using them helps keep the method isolated and helps with debugging through multiple levels of recursion. Generally I find it easiest to write separate public and private functions that handle the recursion. The public function serves as the entry point and then calls the private implementation. The private implementation then can have additional parameters needed to make the recursion work. Once the recursion stops and returns the result, the public method then can assign that to the class member or return it to the caller. If you need your recursive function to return multiple things, you can either return an array or use by-reference parameters. Without more details about what your specific needs are it's hard to make recommendations, but for example something like this for recursively finding files/directories separated by type: class Filesystem { public function getListing($root){ $this->getListingRecursive($root, $files, $directories); return ['files' => $files, 'directories' => $directories]; } private function getListingRecursive($root, &$files, &$directories){ $iter = new FilesystemIterator($root); foreach ($iter as $item){ if ($item->isDir()){ $directories[] = $item->getPathname(); $this->getListingRecursive($item->getPathname(), $files, $directories); } else { $files[] = $item->getPathname(); } } } // Bonus iterative implementation private function getListingIterative($root, &$files, &$directories){ $stack = [$root]; while (null !== ($root = array_shift($stack))){ $iter = new FilesystemIterator($root); foreach ($iter as $item){ if ($item->isDir()){ $stack[] = $directories[] = $item->getPathname(); } else { $files[] = $item->getPathname(); } } } } } I used separate pass-by-reference variables there for the output, but one could just have easily returned an array (like the public method does) and merged the results instead.
  24. Have you tried Net_DNS, as mentioned on the getmxrr manual page?
  25. If one valid course of action is to dump the box and use something else, then there's no reason you can't at least make an effort to upgrade it before using it. Worst case would be you go back to the original plan and dump it. There really shouldn't be any reason you couldn't get a modern OS with updated software on it, or at least a modern PHP version compiled manually. I have some circa 2003 hardware that I was using with FreeNAS and PHP 5.5 for a while just a couple years ago, no problems at all. Currently it's sitting on a shelf doing nothing, but if I ever found a need for it I have no doubts I could just slap a modern Linux OS onto it with current software. Since you mention it being a "closed-source box", I'm going to guess there's a reasonable chance you mean Windows. Even if your using something old like Windows XP you can still update to at least 5.4 by just downloading the appropriate version from windows.php.net
×
×
  • 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.