1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

invisibly detecting browser width and height for first-run-through a PHP script

Discussion in 'PHP' started by seductiveapps.com, Mar 13, 2017.

  1. #1
    index.php :
    
    <?php
    header('cache-control: private, max-age=0, no-cache');
    
    require_once(dirname(__FILE__).'/boot__stage__000.php');
    require_once (dirname(__FILE__).'/globals.php');
    
    global $woWebsite; // PHP class from webappObfuscator-1.0.0/boot.php
    global $woWebsite__factorySettings; // from webappObfuscator-1.0.0/boot.php
    global $woWebsite__clientSettings; // from webappObfuscator-1.0.0/boot.php
    
    global $webappObfuscator; // PHP class from webappObfuscator-1.0.0/boot.php
    global $webappObfuscator__factorySettings; // from webappObfuscator-1.0.0/boot.php
    global $webappObfuscator__clientSettings; // from boot__stage__000.php; client is $saCMS
    global $saConfig__saCloud;
    global $seductiveapps_installedApps;
    global $saCMS; // PHP class from siteFramework-pw-*/*/com/cms/boot.php
    global $saCMS__settings; // from siteFramework-pw-*/*/com/cms/boot.php
    
    //$obfuscatorURL = $woWebsite__clientSettings['URLs']['obfuscator'];
    set_time_limit (0); // re-generation of databases may take a while.
    error_reporting (E_ALL); // TODO : redirect errors for non-developer visitors to a log-file + email to developer..
    set_error_handler ('woBasicErrorHandler');
    
    ?>
            <script type="text/javascript">
           
                function getCookie(cname) {
                    var name = cname + "=";
                    var decodedCookie = decodeURIComponent(document.cookie);
                    var ca = decodedCookie.split(';');
                    for(var i = 0; i <ca.length; i++) {
                        var c = ca[i];
                        while (c.charAt(0) == ' ') {
                            c = c.substring(1);
                        }
                        if (c.indexOf(name) == 0) {
                            return c.substring(name.length, c.length);
                        }
                    }
                    return "";
                };
               
                var 
                browserWidth = function () {
                // iPhone 6 compatible - jQuery.width() is not (jQuery version 2.1.1)
                    return (
                        window.innerWidth
                            ? window.innerWidth
                            : (
                                document.documentElement 
                                && document.documentElement.clientWidth
                                ?document.documentElement.clientWidth
                                :document.body.clientWidth
                            )
                    );
                },
                browserHeight = function () {
                // iPhone 6 compatible - jQuery.width() is not (jQuery version 2.1.1)
                    return (
                        window.innerHeight
                        ? window.innerHeight
                        : (
                            document.documentElement
                            && document.documentElement.clientHeight
                            ?document.documentElement.clientHeight
                            :document.body.clientHeight
                        )
                    );
                };
                var
                w = browserWidth(),
                h = browserHeight(),
                ow = getCookie('browserWidth'),
                oh = getCookie('browserHeight'),
                reload = false;
               
                if (
                    parseFloat(ow)!==parseFloat(w)
                    || parseFloat(oh)!==parseFloat(h)
                ) reload = true;
               
                document.cookie = 'browserWidth='+w+';';
                document.cookie = 'browserHeight='+h+';';
                   
                if (reload) document.location.reload();
            </script>
    <?php 
    reportVariable ('$_COOKIE', $_COOKIE); 
    
    if (array_key_exists('browserWidth',$_COOKIE)) {
        $_SESSION['browserWidth'] = $_COOKIE['browserWidth'];
        $_SESSION['browserHeight'] = $_COOKIE['browserHeight'];
        unset ($_COOKIE['browserWidth']);
        unset ($_COOKIE['browserHeight']);
        //reportVariable ('$_COOKIE', $_COOKIE); 
        die();
    } else {
        die();
    }
    
    
    
    $saAppParams = resolveURLs_functionCalls();
    global $saAppParams;
    
    $saDebugStartup = false;
    
        if (!$saDebugStartup) {
            // normal operations for this website, $_SESSION['browserWidth'] holds the end-users browser-window width, so that appropriately large image files can be used that fill dont overuse bytes yet show you the most detail that is possible on the end-user's system.
            global $useObfuscatedSources;
            $woWebsite->displaySite(null, '/', null, $useObfuscatedSources);
        } else {
            // report a bunch of the initialization settings
            errorHandlingStyleLinks();
    
            reportVariable ('$_SERVER["REDIRECT_QUERY_STRING"]', $_SERVER["REDIRECT_QUERY_STRING"]);
           
            reportVariable ('saAppParams = resolveURLs_functionCalls(); {decodes $_SERVER["REDIRECT_QUERY_STRING"]}', $saAppParams);    
           
            $untranslatedContentURL = $woWebsite->getURLfromLocation();
            reportVariable ('$woWebsite->getURLfromLocation()', $woWebsite->getURLfromLocation());
    
            global $saInstalledApps;
            reportVariable ('global $saInstalledApps', $saInstalledApps);
           
            $call = $woWebsite->getContent($untranslatedContentURL);
            $saContent = result($call);
            reportVariable ('$saContent = result($woWebsite->getContent($untranslatedContentURL))', $saContent);
           
            $saPS = $saCMS->getPageSettings();
            reportVariable ('$saPS = $saCMS->getPageSettings', $saPS);
           
            /*$saMenu = $saCMS->getMainMenu();
            reportVariable ('$saMenu = $saCMS->getMainMenu();', $saMenu);
           
            reportVariable ('$_SERVER["REQUEST_URI"]', $_SERVER['REQUEST_URI']);
           
            $saMeta = $woWebsite->getMetaURL($_SERVER['REQUEST_URI']);
            reportVariable ('$saMeta = $woWebsite->getMetaURL($_SERVER["REQUEST_URI"]);', $saMeta);
           
            $saTitle = $woWebsite->getTitleURL($_SERVER['REQUEST_URI']);
            reportVariable ('$saTitle = $woWebsite->getTitleURL($_SERVER["REQUEST_URI"]);', $saTitle);
           
            reportVariable ('$saCMS->getGoogleAnalytics()', htmlentities($saCMS->getGoogleAnalytics()));
            */
           
            reportVariable ('$_SERVER', $_SERVER);
        }
    ?>
    Code (markup):

     
    seductiveapps.com, Mar 13, 2017 IP
  2. cesarpa

    cesarpa Greenhorn

    Messages:
    10
    Likes Received:
    1
    Best Answers:
    1
    Trophy Points:
    13
    #2
    What do you need? What is this code?

    You can't detected browser width and height in PHP. You can do it in Javascript and send an AJAX request to a PHP handler.
     
    cesarpa, Mar 15, 2017 IP
  3. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #3
    Are you saying you figured out how to do it (with that bloated train wreck of how not to write PHP slopped together from dozens of includes for nothing) or are you asking how to do it? You're not very clear either way.

    @cesarpa -- if you look deeper you'll see he has scripttardery in the code to pull that information, set it as a cookie (wasting bandwidth) and then doing a refresh from the scripting.

    Even so one really shouldn't be giving a flying **** server-side what the client-side dimensions are as you should be outputting semantic markup of content giving a flying purple fish about how that content is going to be shown... since formatting the content to fit the screen is CSS' job... NOT PHP or even JavaScript's. If your server-side language 'needs' to know that information, you're probably doing something horrifyingly and terrifyingly WRONG!

    ... like using PHP or JavaScript to control layout.

    Well, unless it's for tracking, and then the stupid bandwidth wasting reset, lack of scripting off graceful degradation, and fact it looks like you already have Google Analytics loading which would track that for you?

    Really the whole thing reeks of "throwing code at a page for no legitimate reason" as well as pissing on accessibility from orbit.

    Also wouldn't help to clean up your code so it's not such a bloated mess... like the endless var for nothing (which is odd as you do it 'right' in one spot but not another?), lose the attributes we no longer officially need and never actually needed in the first place like "type" on a <script> tag, use a proper trim (polyfilling trim for older browsers is usually the best approach for that) instead of the slow brute force you have there, etc, etc.
     
    deathshadow, Mar 16, 2017 IP
    ThePHPMaster likes this.
  4. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #4
    Uhm, silly question -- just noticed this... why do you have ANY code after:

    
    if (array_key_exists('browserWidth',$_COOKIE)) {
        $_SESSION['browserWidth'] = $_COOKIE['browserWidth'];
        $_SESSION['browserHeight'] = $_COOKIE['browserHeight'];
        unset ($_COOKIE['browserWidth']);
        unset ($_COOKIE['browserHeight']);
        //reportVariable ('$_COOKIE', $_COOKIE); 
        die();
    } else {
        die();
    }
    
    Code (markup):
    Since it die()'s either way? the code after that could NEVER be run.
     
    deathshadow, Mar 16, 2017 IP
  5. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #5
    Oh, and little tip, blindly brute-forcing getting cookies that way -- pretty much blind copypasta from W3Fools -- is pretty inefficient. It's even inefficient/slow compared to a regex, at which point make your life easier and use a more reliable regex.

    Here, try mine:
    
    function cookieGet(name) {
    	return name && (name = document.cookie.match(
    		new RegExp('(^|;)\\s*' + name + '\\s*=\\s*([^;]*)')
    	)) ? unescape(name[2]) : !1;
    }
    
    Code (markup):
    Some browsers insert extra whitespace after you unset or expire a cookie while live, hence all the extra /s* in there. Pain in the ass the first time that one whips around and bites you. Their (W3Fools) pre-string reduction is just silly... as is using URIDecode on something that is NEVER URIencoded. It's escaped... LITTLE bit of a difference there.

    I thought that part of your code looked familiar -- sure enough, there it was. More bad advice from the worst of sources, W3Fools.

    Also if you are REALLY doing something where the server cares about resolution (which it shouldn't) you're gonna trap window.onresize, right?
     
    deathshadow, Mar 16, 2017 IP
  6. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #6
    Just for laughs -- and to get my mind off my back pain -- I thought I'd play with how I'd go about it IF I had to for... some reason that likely doesn't exist.

    I put together an archive of a working demo. Since it screws with caching in a BAD way (inherent to how it would work sadly) I didn't put a copy live.

    http://www.cutcodedown.com/for_others/seductiveApps/browserSize.rar

    I broke it into several sub-files since with PHP being an INTERPRETED language, loading code that you aren't going to run usually isn't all that great a choice -- particularly if you have a perfectly good "IF" statement there SAYING "we're not doing this right now".

    index.php
    
    <?php
    session_start();
    session_regenerate_id();
    if (
    	array_key_exists('browserWidth', $_COOKIE) &&
    	array_key_exists('browserHeight', $_COOKIE)
    ) include('loadWidthHeightCookie.php');
    else if (
    	!array_key_exists('browserSizeGot', $_SESSION) &&
    	!array_key_exists('browserSizeSkip', $_GET)
    ) {
    	include('createWidthHeightCookie.php');
    	die();
    }
    include('normalPageContentsGoesHere.php');
    
    Code (markup):
    Whenever I start sessions I regenerate the ID to reduce the window in which MITM attacks are possible. It's just good practice even if there is a small bit of overhead introduced. (PHP renaming the file directory and the new PHPSESSID cookie).

    The first test is to see if we have gotten new cookies, if so we include the routine to set those values in the sessions (see below). If not we see if our "we got one" variable is set, or if "browserSizeSKip" is set. As you'll see in createWidthHeightCookie that $_GET parameter is passed so we can have scripting off graceful degradation, so whatever it is you want to do with that width, check that value first!

    If neither of those are set, we load the routine to create those cookies and die. Otherwise, load the normal page contents.

    loadWidthHeightCookie.php
    
    <?php
    $_SESSION['browserWidth'] = $_COOKIE['browserWidth'];
    $_SESSION['browserHeight'] = $_COOKIE['browserHeight'];
    $_SESSION['browserSizeGot'] = true;
    unset($_COOKIE['browserWidth']);
    unset($_COOKIE['browserHeight']);
    
    Code (markup):
    Pretty much just sets the values, including the "yeah, we got it" flag. Unsetting the cookies lets us detect when the values have changed. I put this separate since in 99% of page loads it is highly unlikely the window size has actually changed.

    createWidthHeightCookie.php
    
    <?php header('cache-control: private, max-age=0, no-cache'); ?>
    <!DOCTYPE html><html><head><meta charset="utf-8">
    <noscript>
    	<meta http-equiv="refresh" content="0; url=?browserSizeSkip=1">
    </noscript>
    <title>One moment</title>
    </head><body><script>
    	var d = document, de = d.documentElement;
    	d.cookie = 'browserWidth=' + de.clientWidth;
    	d.cookie = 'browserHeight=' + de.clientHeight;
    	d.location.reload();
    </script></body></html>
    
    Code (markup):
    Setting them just keep the document as simple as possible. The noscript fallback setting our $_GET value is VERY important, I use a few variables just to shrink the code a bit (this is something I'd consider minifying, and I don't minify often!)

    An Empty document has no scrollbars, so there's no reason to waste fancy code tricks when ddE.client is uniform with window values. Honestly I'd use documentElement.clientWidth either way since it subtracts scrollbars! Window.innerWidth doesn't which can make it pretty damned useless.

    Oh, and you might want to send a header() later on to set at least a small cache time since you wouldn't want that initial load to screw up your caching models once you know how big the screen is.

    In your normal page right before </body> I would then:
    
    <script>
    	var
    		browserWidth = <?= $_SESSION['browserWidth'] ?>,
    		browserHeight = <?= $_SESSION['browserHeight'] ?>;
    </script>
    <script src="browserSizing.js"></script>
    
    Code (markup):
    Keeping as much of the static code where it can be cached.

    browserSizing.js
    
    (function(d) {
    
    	var de = d.documentElement;
    	
    	function eventAdd(e, event, callback) {
    		if (e.addEventListener) e.addEventListener(event, callback, false);
    		else e.attachEvent('on' + event, callback);
    	}
    	
    	function resizeCallback() {
    		if (
    			browserWidth != de.clientWidth ||
    			browserHeight != de.clientHeight
    		) {
    			d.cookie = 'browserWidth=' + (browserWidth = de.clientWidth);
    			d.cookie = 'browserHeight=' + (browserHeight = de.clientHeight);
    		}
    	}
    	
    	eventAdd(window, resize, resizeCallback);
    	resizeCallback();
    	
    })(document);
    
    Code (markup):
    This will change/set the cookies if the values start out different or if the user resizes it. That will then trip the change to those values on the next pageload in that central index.php!

    If it's ACTUALLY "essential" functionality, you might consider sending it via AJAX instead of by cookie when a resize triggers.

    Again, NOT that there should EVER be a legitimate reason for the SERVER to know these numbers... but it's a fun experiment to see about passing data back to the server as quickly and quietly as possible. Reducing the size of the file being sent during data retrieval AND providing a scripting-off fallback are the big important parts when such information retrieval is desired.

    Said technique could be VERY useful for making your own stats tracking package. That's about the only time I could even concieve of the server needing to know that number.

    ... and look, JS doesn't even have to screw with pulling the cookie.
     
    deathshadow, Mar 16, 2017 IP
  7. seductiveapps.com

    seductiveapps.com Active Member

    Messages:
    200
    Likes Received:
    6
    Best Answers:
    0
    Trophy Points:
    60
    #7
    well i did some testing, and the windows still look crap, with the borders of a single PNG dialog background image getting stretched to the point of pure ugliness no matter what i do.
    starting today, i'm gonna build a canvas solution for my dialog background art needs.
     
    seductiveapps.com, Mar 21, 2017 IP
  8. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #8
    Wait, are you trying to use this to scale a background image and/or specially construct it for certain sizes?

    Are there tileable subsections of these images? If so, that's CSS' job, not the server or the HTML's... at least in modern browsers.

    Whilst MOST people talking CSS are talking about controllable opacity, rounding corners, and so forth, a very cool and VERY overlooked feature is border-image.

    https://developer.mozilla.org/en-US/docs/Web/CSS/border-image

    That might be able to do what you are looking for... Though on the IE side of things it's IE11+ only. For anyone still using older browsers I'd just feed them an attractive solid colour and then say "OH WELL!".

    If you would care to share the image/style "windows" you are trying to implement, I could probably toss up a pure HTML/CSS equivalent pretty quickly unless your image concepts simply aren't "viable for web deployment" -- sadly, that is far too often the case with some design ideas.

    You may have dove for the PHP solution too quickly -- just like how it's VERY easy to dive for the JavaScript solution too quickly as well. A LOT of what people do on the server or in the client-side scripting really doesn't belong in either.

    See about two thirds of "react.js" codebase... or 80% or so of jQuery's...

    Though "dialog background art" is a troublesome concept... but I'm one of those nutters who still practices template size targets of 144k or less. I can't do a template in that much code (that's HTML + JS + CSS + non-content images) -- not counting content or social media/discussion plugins (like disqus)-- it doesn't go on the web. Actually, I say 144k, but that's me Mr. Scotting my numbers. Figure out what you REALLY need, then double it.

    Many background-images people use on sites blow past my limits all on their lonesome.
     
    deathshadow, Mar 22, 2017 IP