Jump to content
#StayAtHome ×

requinix

Administrators
  • Content Count

    11,971
  • Joined

  • Last visited

  • Days Won

    254

Everything posted by requinix

  1. I derived this monstrosity for work*: we had arbitrary HTML and I needed to cut it down to a certain number of words, not counting headings, and preserving as much markup as possible. Slightly redacted. For regular use, one would probably want to make a couple adjustments like removing the check for "foo_" and "foohead" (both indicating heading markup). /** * Truncate raw content * * @param mixed $content * @param int $words * @param bool $headings * @return array */ private static function truncateRaw($content, $words, $headings = false) { if(is_array($content)) { $ret = array('content' => array(), 'remaining' => $words); foreach($content as $key => $value) { if($ret['remaining'] <= 0) { if($ret['remaining'] == 0) { $ret['content'][$key] = '...'; } break; } $remaining = $value->truncate($ret['remaining'], $headings); $ret['content'][$key] = $value; $ret['remaining'] = $remaining; } return $ret; } else { $ret = array('content' => '', 'remaining' => $words); if($words <= 0) { return $ret; } // some special content has html comments explicitly marking a preview area if(($pos1 = strpos($content, '<!-- BEGIN PREVIEW -->')) !== false && ($pos2 = strpos($content, '<!-- END PREVIEW -->', $pos1)) !== false) { // 22 for strlen('<!-- BEGIN PREVIEW -->') $len = $pos2 - $pos1 - 22; $ret['content'] = trim(substr($content, $pos1 + 22, $len)); $ret['remaining'] = 0; } else { // cut the text in a way to preserve html tag structure $pieces = preg_split('#(</?(\w+).*?>)#is', $content, -1, PREG_SPLIT_DELIM_CAPTURE); // comes in triplets $excerpt = array(); $tags = array(); $header = 0; // counter for tag depth in headers $state = 0; // piece A: 0=text // piece B: 1=html tag // piece C: 2=open tag name, 3=opening tag name of header, 4=self-closing tag, 5=closing tag name // // A B C // +----+------+------------------------+ // | 0 -|-> 1 -|-> 2 if opening tag -|-> 0 and header++ (if header>0) // +----+------+------------------------+ // | 0 -|-> 1 -|-> 3 if opening header -|-> 0 and header++ // +----+------+------------------------+ // | 0 -|-> 1 -|-> 4 if self-closing -|-> 0 // +----+------+------------------------+ // | 0 -|-> 1 -|-> 5 if closing tag -|-> 0 and header-- (if header>0) // +----+------+------------------------+ // // break text if header==0, otherwise only increase word count // // h1 h2 h1 h0 // 013 0 12 0 15 015 014 012 0 15 0 // <p class="foo_header">Header <b>Text</b> </p> <br /> <p>Content</p> // ^ header ^ not header foreach($pieces as $piece) { // 0. text if($state == 0) { if($header) { if($headings) { $cut = self::cutWords($piece, $ret['remaining']); $excerpt[] = $cut['content']; $ret['remaining'] = $cut['remaining']; } else { $excerpt[] = $piece; $ret['remaining'] -= self::countWords($piece); } } else { $cut = self::cutWords($piece, $ret['remaining']); $excerpt[] = $cut['content']; $ret['remaining'] = $cut['remaining']; if($ret['remaining'] <= 0) { break; } } $state = 1; } // 1. html tag else if($state == 1) { // logic is easier to write in reverse order if($piece[1] == '/') { // closing // closing tag logic will decide when to add itself to the excerpt $state = 5; } else if(substr($piece, -2, 1) == '/') { // self-closing $excerpt[] = $piece; $state = 4; } else if(strlen($piece) >= 3 && $piece[1] == 'h' && ctype_digit($piece[2])) { // normal header $excerpt[] = $piece; $state = 3; } else if(strpos($piece, 'foo_') !== false || strpos($piece, 'foohead') !== false) { // old header $excerpt[] = $piece; $state = 3; } else { // text $excerpt[] = $piece; $state = 2; } } // 2. opening tag else if($state == 2) { $header && $header++; $tags[] = $piece; $state = 0; } // 3. opening header else if($state == 3) { $header++; $tags[] = $piece; $state = 0; } // 4. self-closing else if($state == 4) { $state = 0; } // 5. closing tag else if($state == 5) { $header && $header--; while($tags && $tag = array_pop($tags)) { $excerpt[] = "</{$tag}>"; if($tag == $piece) { break; } } $state = 0; } } // clean up any unclosed tags while($tags && $tag = array_pop($tags)) { $excerpt[] = "</{$tag}>"; } $ret['content'] = implode('', $excerpt); } return $ret; } }The most important thing was that it put tags onto a stack in order to close them out properly when the content gets cut inside multiple tags - I had to deal with things like ULs and tables. OR, instead of all this crazy work deciding how to get a summary: ask the writer to write one. Seriously. It's so much easier and their summary will be nicer than one you come up with automatically. * I don't normally like sharing stuff done for my job, IP rights and whatnot, but we're fairly lax and this is one of those times when there can be significant benefit to the community.
  2. No, what you did was tell PHP where it should search for files when you try to include them. Completely different thing.
  3. With just ->item, SimpleXML will always get the first element named "item". Use $xmlappend->addChild to create a new item each time, put that in a variable, and add the title and URL to that.
  4. Go for an MP4 (which is just a "container" for stuff) using H.264 video and AAC or MP3 audio. Not sure how you did the conversion but make sure you're converting to those formats. Could be you converted without audio, or to an audio codec not supported by WMP or the browser. Is the MOV (preferably) or MP4 (to see what's wrong) online somewhere we can see? Very wrong.
  5. Is this not something you can just do manually? Not many good reasons why you should be able to execute arbitrary SQL files on a regular basis. Fewer that require you to use PHP instead of, say, a cronjob.
  6. The firstColor is inside the color array which is inside the $m_array array. $m_array["color"]["firstColor"]
  7. There is an easier way: make sure the tag column is unique and do an INSERT IGNORE with all the tags at once. INSERT IGNORE INTO blogTags (tag) VALUES ("tag1", "tag2", "tag3")which will be easier to do without prepared statements.
  8. What's your full code so far? What have you tried? How did it not work?
  9. You can't put BRs between table cells like that. The browser has to try to deal with the invalid markup you've given it, and it apparently does so by interpreting those as being placed before the table.
  10. Just because it uses the same = symbol doesn't mean it works the same way. That does not make sense. Rewrite the expression in terms of X alone. Meaning you have to end up at X = ....
  11. GoDaddy has nothing to do with that, and if you move then you'll still have that same problem. It has to do with your stuff. Two different things. Can't have a CDN without a backend host, in one form or another. CDNs are about distributing static content by using lots of servers scattered around the world, each with a copy of the files you're trying to serve. With servers closer to the users, yes that means lower latency. A place like the PHP Freaks forums cannot use a CDN for the threads and posts and such because that isn't static, but it can use one for the CSS and images and other files that its pages need that don't change often. No one guarantees 100% uptime. What they will guarantee, if anything, is a certain number of "9s". For example, "five 9s" means 99.999% (which is about 25 seconds of downtime per month, on average).
  12. They do have permissions, it seems you're just not able to see them. (Must be that the FTP server or client just doesn't want to show you.) Unless you're saying they have permissions 0000, which is a very bad thing. PHP is running as a different user than you, meaning when it creates files and folders they will have a different owner (but likely still 0644/0755). That's something for you to keep in mind: - If the uploads folder was created by PHP then you (via FTP) will not be able to delete or rename or otherwise affect files within that folder... unless you modify the permissions of the files/folder within PHP. But you probably don't need to do that. - If you created the uploads folder then it'll need to be 0777 so that PHP (which is subject to the "other" permission set) can put files in there.
  13. Not really. If you wanted better security then you should actually move to a dedicated box - so there aren't other, untrusted users on the same machine. But you probably don't need the added security. As a test of something, do a file upload through PHP and place the file wherever. This can just be a little test script you write quickly. When you look at the file through FTP, what user and group does it belong to?
  14. It should already be set up so that everything you create via FTP is owned by you and your group, files are created 0644, and folders are 0755. If you create things via PHP, which includes doing file uploads, then it will be a little different.
  15. If it's a shared server, as in shared hosting that you get from some company online, then you don't do anything. The hosting company manages it.
  16. Don't make it more complicated than it needs to be. Add a column to whatever table you're using to hold the HTML-ready version, alongside the raw BBCode version. Yes, it doubles disk space, but disk space is cheap and plentiful while your time is not.
  17. Your taught your computer that application/force-download type is a "Wave Sound". The thing that triggers the download is the Content-Disposition header, so leave the Content-Type with the right value. Unfortunately that varies by file, and you probably aren't recording it anywhere accessible. You should install something like fileinfo in order to get the type based on the file contents (your only recourse), but if that's not an option, header("Content-Type: application/octet-stream");the application/octet-stream type is your best option because it has an official meaning, unlike application/force-download (which someone simply made up).
  18. requinix

    Pixel Tracking

    Why go through GD? 1. Make a 1x1 transparent pixel in MS Paint or whatever, save as GIF for the small size. 2. Do echo base64_encode(file_get_contents("/path/to/pixel.gif")) and copy that. 3. Paste it in code as header("Content-Type: image/gif"); echo base64_decode("base64 encoded stuff here");
  19. mysqli_query("$conn, $deleteQuery, ");Not sure why those quotes are there, but they shouldn't be.
  20. Not sure what to say. Looks like you're doing everything right and IE is pulling the underscore out of nowhere... It still has the underscore when you save the file, right? Tried another browser?
  21. $_GET won't do that. Which is an array, by the way, not a function. You need two functions: rawurlencode and htmlspecialchars(). Applied to $file in that order. And htmlspecialchars() alone for the second $file. echo " ", htmlspecialchars($file, ENT_QUOTES), " ";That's because the filename is going into a URL, and you're putting that URL within HTML. When the browser figures out what to do when you click the link, it will HTML-decode the URL first (because it's in HTML) and then verify it is an acceptable URL (and if not, URL-encode it automatically because it's nice like that). In download.php you only look in $_GET: there will be no HTML encoding and the URL decoding happened earlier (since, being in a URL, PHP knew it must necessarily happen at some point anyways).
  22. Simply accessing a non-existent property will not fatal code unless (a) access goes through __get which fatals by itself or (b) you try to do certain types of actions with that value, such as call a method on it. Your live website should keep those 500 errors in place: displaying error messages to the user is not a good thing. Instead, check your error log, be that the Apache log or a dedicated PHP error log.
  23. I was saying that because of: (your application doesn't know the columns in the table so it has to query the metadata for them) (you say you're copying tables) (creating tables) ("many tables" and you're copying them around) (tables are changing schema on a regular basis)
  24. My first reaction is "Why are you creating so many tables?", followed by "Why doesn't your application know the table structures already?"
×
×
  • 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.