PHPで来月末を取得

PHPで来月末を取得するときに苦戦しました。
調べるとほいほいでてくるんですがstrtotime関数の+1 monthが安定していないだのなんだので、結構不安だったからです。ちゃんと理屈で自分が納得行くものを利用したいので…。結論としては以下のコードで取得可能です。

これを少し解説したコードが以下

これは2018年12月6日に実行した場合です。最初はなんでこれで月末が帰ってくるのかわからなかったんですが、date(‘Y-m-t’)の’t’を見落としていました。日付フォーマットの’t’は

指定した月の日数。
http://php.net/manual/ja/function.date.php

とあるので、1月なら30が、2月なら28が帰ってきます(うるう年なども考慮されるかと)。
簡単に見えますが、落とし穴たくさんありそうなので、いろいろ試してみました。

This support library should not use a different vesion than the compileSdkVersion

Android supportライブラリなどで利用するべきバージョンについて(サンプル有)

Androidのgradleのdependenciesのimplementation(旧 compile)でよく出るこのWarning。

StackOverflowとかで見て、このエラーでビルドできないからこれ、と闇雲にライブラリのバージョンを指定していると、こうなりますよねw

ほっといてもビルドできる時もありますが、時にできなくなって、できない時は本当にカオスでわけわかめになります。

なので、ちゃんとやった方がいいです。

じゃあ、どのバージョンを指定したらいいのー??ってなりますが、その方法を書いておきます。

下記のようにアプリケーションのbuild.gradleファイルを作ったとすると

apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'


android {
    compileSdkVersion 27
    buildToolsVersion '28.0.3'
    defaultConfig {
        applicationId "hogehoge"
        minSdkVersion 14
        targetSdkVersion 27
        javaCompileOptions {
            annotationProcessorOptions {
                includeCompileClasspath false
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
    useLibrary 'org.apache.http.legacy'
    productFlavors {
    }
}

dependencies {
    compile project(':rateThisApp')
    compile 'com.android.support:support-v4:27.1.1'
    compile 'com.google.android.gms:play-services-location:16.0.0'
    compile files('lib/osmbonuspack_v4.2.9.jar')
    compile files('lib/osmdroid-android-4.1.jar')
    compile files('lib/osmdroid-third-party-4.1.jar')
    compile files('lib/slf4j-android-1.6.1-RC1.jar')
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support:design:27.1.1'
    implementation 'com.google.firebase:firebase-messaging:17.3.4'
    implementation 'com.google.android.gms:play-services-maps:16.0.0'  // GoogleMapを使うために追加する

}

compileSdkVersion 27のこの数字にサポートライブラリのバージョンの最初の数字を合わせます。

サポートライブラリとは、

'com.android.support:support-v4:27.1.1'

いたいなやつのことです。上記の意味は、com.android.support:support-v4というライブラリのバージョン27.1.1ですよ!ってことです。

つまり、compileSdkVersion が27だから、ライブラリのバージョンの最初の数字は27です。

後のやつはどうやって決めるの?というと、下記のサイトで探します。

Recent Support Library Revisions

https://developer.android.com/topic/libraries/support-library/revisions?hl=ja

例えば、上記のサイトを見ると、バージョン27だと、現在(2018/12/04)で
Revision 27.1.1
が最新ということになります。

なので、

'com.android.support:support-v4:27.1.1'

として、27.1.1を指定します。

AndroidManifest.xmlのminSdkVersionを変更しても反映されずビルドできない

さて、ADTのプロジェクトをAndroid Studioへ移す過程ではまったエラー対策の続きです。Android Studioはバージョン3.2.1です。

前回のことがあり、ようやくエラーの原因がわかりました。

C:\Android\takuru\ASdriver1\hogehoge\src\main\AndroidManifest.xml:7:5-74 Error:
uses-sdk:minSdkVersion 11 cannot be smaller than version 14 declared in library [com.google.android.gms:play-services:12.0.1] C:\Users\hogehoge\.gradle\caches\transforms-1\files-1.1\play-services-12.0.1.aar\93010549a0eaa8ce0a656b526c4ad348\AndroidManifest.xml as the library might be using APIs not available in 11
Suggestion: use a compatible library with a minSdk of at most 11,
or increase this project's minSdk version to at least 14,
or use tools:overrideLibrary="com.google.android.gms.play_services" to force usage (may lead to runtime failures)
:takuruDriver:processDebugManifest

 

ご丁寧にもダメなAndroidManifest.xmlへのリンクもあります。

「ほうほう。AndroidManifest.xmlのminSdk指定が悪いのね~ 11じゃなくって14にすればいいんでしょー?!」

っとちゃかちゃか直して、Gradle Sync。

そしたら、Sync Failured.なんですよ。なんで。(´・ω・)

また、プロジェクトをBuild→cleanします。

すると、また下記の同じエラー出てるんですよ。

Error:uses-sdk:minSdkVersion 11 cannot be smaller than version 14.....

ファッ?!ってなって、もう一度、AndroidManifest.xmlを見直したり、キャッシュを消したり、.gradleを消したり。
してみても、結果は一緒でした。。。

なんでAndroidManifest.xmlのminSdkVersionを変更しても反映されないの??と思っていたら、偶然にもAndroidManifest.xmlの下記の部分にマウスオーバーしたら

The minSdkVersion value(14) is not used. it is always overridden by the value specified in the Gradle build script (14) ...

ってメッセージが出てるんですよ。

「…あっ…」

そうですね、プロジェクトのbuild.gradleにもminSdkVersionを書くところがあり、そのほうがAndroidManifest.xmlよりも優先されるのだった。

build.gradleにある下記のminSdkVersionを直して、

android {
    compileSdkVersion 26
    buildToolsVersion '28.0.3'

    defaultConfig {
        applicationId "hogehoge.driver"
        minSdkVersion 14 //これを11から変更
        targetSdkVersion 26
    }
//以下略

AndroidManifest.xmlにあるminSdkVersionは紛らわしいので消します。

すると、やっとBuildが通り、Gradle Syncも成功しました!!( ˊᵕˋ )

Gradle project sync failed. Basic functionality (e.g. editing, debugging) will not work properly.

ADT(Eclipse)で開発していたAndroidプロジェクトに手を入れる必要があり、Android Studioへ移行しました。

とってもつらたんな作業でした…(つД`)

前も言いましたが、ビルドできるのが当たり前と思っているとイライラするので、むしろビルドできる奇跡に感謝しよう。( ̄人 ̄)

さて、今回はまったポイントがいくつかあるので、記載しておきます。

Android Studioのバージョンは3.2.1です。

一番困ったのは、タイトルのエラー。

Gradle project sync failed. Basic functionality (e.g. editing, debugging) will not work properly.

 

GradleのSyncをやると、出てくるんですよ。

Buildのウィンドウにはエラーが何も出てない。show error logってリンク見て、エラーログを見ても、結局失敗して終わってるな~ という以外にエラーは記載されていません。

さて、困った。

で、.gradleを消すとか、キャッシュを消すとか、Android Studio(以下、ASと略します)を再起動させるとかいろんなことを試してみたんですが、役にたったのがこれ。

①ヘッダーメニューのFile→Setting→Build, Execution,DeploymentのCompilerのCommand-line Optionsで

--stacktrace

を指定。–debugはこの場合役に立たない、とエラーメッセージが言ってますからね。

②ヘッダーメニューのBuild→Clean Project

すると、ビルドのウィンドウにメッセージが出ます。。。

あれー、前はGradle Syncの失敗でも、ビルドのウィンドウにメッセージ出たと思ったんだけど…。ASのアップデートで仕様が変わったんでしょうか。

やっとエラーの原因がわかって先に進むことができました!

 

 

 

PHPでHTML文字列の作成

PHPでHTML文字列を作成するときに困ってしまいました。具体的にはPDFファイルを作成するのにHTMLが必要だったときです。
最初に試した方法は以下のようなもの

これだとHTML構造がわかりにくく、HTML構造の変更にも弱いです。
次にヒアドキュメントも試しましたが、今度はPHPの埋め込みがうまくできずいい方法を探していました。
そこでob_start()関数を使うことに。
ob_start

ob_startは標準出力のバッファリングが可能となります。簡単にいうとechoやprintしたものがそのまま出力されずバッファされます。その他<?php ?>タグ以外で書かれたものもバッファするのでそれを利用しました。
obはおそらくoutput bufferingの略でしょうか(違ったら教えてください…)

 

こうすることでhtml構造をわかりやすく表示しつつ、変数の埋め込みも可能となりました。PHPでViewを作っているときと同じ感覚で作成できるのではないかと思います。使用方法も簡単で出力をob_start()で始め、ob_get_clean()で閉じますob_get_clean()の戻り値がバッファの内容となります。